class SeminarMain
  require 'fileutils'
  include Mongoid::Document
  include Mongoid::Timestamps

  include OrbitModel::Impression
  # encoding: utf-8
  include OrbitCategory::Categorizable
  include Slug
  ChoiceTypes = ["checkbox","radio","select"]
  ExceptFieldSetDisplays = ["password", "recaptcha"]
  field :enable_recaptcha, :type => Boolean
  field :annc_count, :type => Integer, :default => 0
  field :album_count, :type => Integer, :default => 0
  field :copy_id
  field :except_clone_relations, :type=>Array, :default => []
  field :signup_note, localize: true
  field :title, as: :slug_title, type: String, localize: true
  field :speaker, localize: true
  field :content, localize: true
  field :act_place, localize: true
  field :enable_summary_choice, :type => Boolean, :default => false
  field :summary_chioice_type, :type => String, :default => "checkbox"
  field :summary_chioices, :type => Array, :default => ["A. Energy Conversion","B. Biocatalysis","C. Electrocatalysis",
                                                        "D. Photocatalysis","E. Catalytic and Porous Materials",
                                                        "F. Environmental and Reaction Engineering","G. Industrial Applications",
                                                        "H. Student Oral Presentation Contest (in English)","I. Student Poster Competition"
                                                        ]
  field :seminar_start_date, :type => Date, :default => Date.today
  field :seminar_end_date, :type => Date, :default => Date.today

  field :signup_start_date, :type => Date, :default => Date.today
  field :signup_end_date, :type => Date, :default => Date.today

  field :contribute_start_date, :type => Date
  field :contribute_end_date, :type => Date
  
  field :contribute_file_count, type: String

  field :registration_status , :type => Array #C: 投稿者 G:一般

  field :create_user_id
  field :update_user_id
  field :reviewer_ids
  field :reviewer_show_ids
  field :session_show_ids
  field :unassigned_seminar_signup_ids
  field :unassigned_mode_1_seminar_signup_ids
  field :review_start_date, :type => Date
  field :review_end_date, :type => Date
  field :last_serial_number, :type => Integer, :default => 0
  field :assign_mode, :type => Integer, :default => 0 # 0 => 用default signup ids來分配 ,1 => 用final_session來分配, 2 => 用final_session來分配(當有preffered session欄位時)
  field :update_old_flag, :type => Boolean, :default => false

  field :signup_limit, :type => Integer, :default => nil

  belongs_to :seminar_item
  belongs_to :organizer , :class_name=>"MemberProfile", :foreign_key => :organizer_id
  has_many :seminar_sessions, :autosave => true, :dependent => :destroy
  has_many :seminar_links, :autosave => true, :dependent => :destroy
  has_many :seminar_files, :autosave => true, :dependent => :destroy
  has_many :seminar_item_contents, :autosave => true, :dependent => :destroy
  has_many :seminar_signups, :autosave => true, :dependent => :destroy
  has_many :seminar_submission_fields, :autosave => true, :dependent => :destroy
  has_many :seminar_signup_fields, :autosave => true, :dependent => :destroy
  has_many :seminar_reviews, :autosave => true, :dependent => :destroy
  has_many :seminar_signup_field_sets, autosave: true, dependent: :destroy
  has_many :seminar_submission_field_sets, autosave: true, dependent: :destroy
  has_many :seminar_email_sets, autosave: true, dependent: :destroy
  has_many :seminar_signup_field_customs, :autosave => true, :dependent => :destroy
  has_one :seminar_template_setting, :autosave => true, :dependent => :destroy
  accepts_nested_attributes_for :seminar_sessions, :allow_destroy => true
  accepts_nested_attributes_for :seminar_links, :allow_destroy => true
  accepts_nested_attributes_for :seminar_files, :allow_destroy => true
  accepts_nested_attributes_for :seminar_item_contents, :allow_destroy => true
  accepts_nested_attributes_for :seminar_signups, :allow_destroy => true
  accepts_nested_attributes_for :seminar_submission_fields, :allow_destroy => true
  accepts_nested_attributes_for :seminar_signup_fields, :allow_destroy => true
  accepts_nested_attributes_for :seminar_reviews, :allow_destroy => true
  accepts_nested_attributes_for :seminar_signup_field_sets, :allow_destroy => true
  accepts_nested_attributes_for :seminar_submission_field_sets, :allow_destroy => true
  accepts_nested_attributes_for :seminar_email_sets, :allow_destroy => true
  accepts_nested_attributes_for :seminar_signup_field_customs, :allow_destroy => true
  accepts_nested_attributes_for :seminar_template_setting, :allow_destroy => true
  before_save do
    if self.signup_limit == 0
      self.signup_limit = nil
    end
    if self.signup_limit_changed?
      self.sync_signup_count
    end
    if !(self.new_record?) && self.title_changed?
      name_hash = {}
      self.title_translations.each do |l, t|
        name_hash["name.#{l}"] = t
      end
      Page.where(:parent_page_id=>self.id).update_all(name_hash)
    end
    module_app_key = "seminar"
    add_module_app_member_ids = []
    remove_module_app_member_ids = []
    if self.reviewer_ids_changed? && (self.copy_id.nil? || !self.new_record?)
      new_reviewer_ids = self.reviewer_ids.to_a - self.reviewer_ids_was.to_a
      remove_reviewer_ids = self.reviewer_ids_was.to_a - self.reviewer_ids.to_a
      new_reviewer_ids.each do |reviewer_id|
        SeminarReview.create(:reviewer_id=>reviewer_id,:seminar_main=>self)
        add_module_app_member_ids << reviewer_id
      end
      remove_reviewer_ids.each do |reviewer_id|
        SeminarReview.where(:reviewer_id=>reviewer_id,:seminar_main=>self).destroy
        remove_module_app_member_ids << reviewer_id
      end
      unassigned_seminar_signup_ids = self.seminar_signup_ids.map{|s| s.to_s}
      seminar_reviews = self.seminar_reviews
      unassigned_mode_1_seminar_signup_ids = unassigned_seminar_signup_ids.dup
      seminar_reviews.each do |sr|
        unassigned_mode_1_seminar_signup_ids = unassigned_mode_1_seminar_signup_ids - sr.get_all_seminar_signup_ids(1)
        unassigned_seminar_signup_ids = unassigned_seminar_signup_ids - sr.all_seminar_signup_ids
      end
      self.unassigned_mode_1_seminar_signup_ids = unassigned_mode_1_seminar_signup_ids
      self.unassigned_seminar_signup_ids = unassigned_seminar_signup_ids
    end
    if self.organizer_id_changed?
      if self.organizer_id_was.present?
        remove_module_app_member_ids << self.organizer_id_was
      end
      if self.organizer_id.present?
        add_module_app_member_ids << self.organizer_id
      end
    end
    remove_module_app_member_ids.delete(self.organizer_id)
    self.reviewer_ids.each{|r| remove_module_app_member_ids.delete(r)} rescue nil
    remove_module_app_member_ids.each do |m_id|
      user = User.where(:member_profile_id=>m_id).first
      begin
        user.extra_link_module_app_keys.delete(module_app_key)
        user.save
      rescue
        next
      end
    end
    add_module_app_member_ids.each do |m_id|
      user = User.where(:member_profile_id=>m_id).first
      begin
        user.extra_link_module_app_keys << module_app_key
        user.save
      rescue
        next
      end
    end
    if self.enable_summary_choice
      (0...self.summary_chioices.count).to_a.each do |i|
        seminar_session = self.seminar_sessions.where(:key=>i).first
        if seminar_session.nil?
          self.seminar_sessions << SeminarSession.new(:key=>i)
        end
      end
      (self.summary_chioices.count...self.summary_chioices_was.to_a.count).to_a.each do |i|
        self.seminar_sessions.where(:key=>i).destroy
      end
    end
  end
  before_create do
    self.unassigned_seminar_signup_ids = []
    self.unassigned_mode_1_seminar_signup_ids = []
    if self.copy_id.present?
      self.clone_new(true)
      self.created_at = DateTime.now
      self.updated_at = DateTime.now
    end
  end
  after_create do
    if self.copy_id.present?
      self.seminar_signup_fields.each do |seminar_signup_field|
        seminar_signup_field.seminar_signup_values.update_all(:key=>seminar_signup_field.key)
      end
      self.seminar_submission_fields.each do |seminar_submission_field|
        seminar_submission_field.seminar_submission_values.update_all(:key=>seminar_submission_field.key)
      end
      current_reviewer_ids = self.reviewer_ids.to_a
      self.seminar_reviews.where(:reviewer_id.nin=>current_reviewer_ids).destroy
      module_app_key = "seminar"
      current_reviewer_ids.each do |reviewer_id|
        seminar_review = self.seminar_reviews.select{|sr| sr.reviewer_id == reviewer_id}.first
        if seminar_review.nil?
          self.seminar_reviews << SeminarReview.create(:reviewer_id=>reviewer_id,:seminar_main=>self)
          user = User.where(:member_profile_id=>reviewer_id).first
          if user.present?
            user.extra_link_module_app_keys << module_app_key
            user.save
          end
        end
      end
    end
  end
  after_destroy do
    Thread.new do
      Page.where(:bind_model=>self.class.to_s,:bind_uid=>self.uid).destroy
    end
  end
  def migrate_old
    unless self.new_record? || @triggered_initialize
      @triggered_initialize = true
      save_flag = false
      seminar_reviews = self.seminar_reviews
      if seminar_reviews.present?
        if self["reviewer_ids"].nil?
          self["reviewer_ids"] = seminar_reviews.pluck(:reviewer_id).flatten.select{|s| !s.nil?}.to_a
          save_flag = true
        else
          self["reviewer_ids"].each do |reviewer_id|
            seminar_review_to_destroy = seminar_reviews.where(:reviewer_id=>reviewer_id)[1]
            if seminar_review_to_destroy
              seminar_review_to_destroy.destroy
            end
          end
        end
        if seminar_reviews.count != 0 && self.review_start_date.nil? && self.review_end_date.nil?
          review_start_date = seminar_reviews.pluck(:review_start_date).select{|t| t.present?}.first.to_datetime rescue nil
          review_end_date = seminar_reviews.pluck(:review_end_date).select{|t| t.present?}.first.to_datetime rescue nil
          self.review_start_date = review_start_date
          self.review_end_date = review_end_date
          if (self.review_start_date_changed? || self.review_end_date_changed?)
            save_flag = true
          end
        end
      end
      if self.unassigned_seminar_signup_ids.nil?
        self.unassigned_seminar_signup_ids = self.seminar_signup_ids.map{|s| s.to_s}
        save_flag = true
      end
      if self.unassigned_mode_1_seminar_signup_ids.nil?
        self.unassigned_mode_1_seminar_signup_ids = self.seminar_signup_ids.map{|s| s.to_s}
        save_flag = true
      end
      unless self.last_serial_number_changed_from_default?
        self.seminar_signups.sort_ordered.each do |ss|
          if ss.serial_number.nil?
            self.last_serial_number += 1
            ss.serial_number = self.last_serial_number
            ss.save(:validate=>false)
            save_flag = true
          end
        end
      end
      self.save(:validate=>false) if save_flag
    end
  end
  def get_frontend_url(tmp_seminar_url, call_action=nil)
    @enable_custom_template = self.enable_custom_template
    if call_action.nil?
      if @enable_custom_template
        extra_url = '/home/registration'
      else
        extra_url = ''
      end
    elsif call_action == :show_data
      if @enable_custom_template
        extra_url = '/home/introduction'
      else
        extra_url = '?method=show_data'
      end
    else
      if @enable_custom_template
        extra_url = "/home/submission"
      else
        extra_url = "?method=#{call_action}"
      end
    end
    tmp_seminar_url + extra_url
  end
  def update_enable_recaptcha
    self.enable_recaptcha = (self.seminar_signup_field_sets.where(:field_name=>'recaptcha', :disabled.ne=>true).count != 0)
    self.save
  end
  def sync_signup_count
    if defined?(OrbitHelper::SharedMutex)
      seminar_id =self.id.to_s
      OrbitHelper::SharedMutex.synchronize do
        if self.signup_limit.nil?
          OrbitHelper::SharedHash['seminar'][:counter][seminar_id] = nil
        else
          signup_count = SeminarSignup.where(:seminar_main_id=>self.id).count
          OrbitHelper::SharedHash['seminar'][:counter][seminar_id] = signup_count
        end
      end
    end
  end
  def signup_is_full?
    tmp_signup_limit = self.signup_limit
    return false if tmp_signup_limit.nil?
    if defined?(OrbitHelper::SharedMutex)
      seminar_id =self.id.to_s
      signup_count = 0
      OrbitHelper::SharedMutex.synchronize do
        signup_count = OrbitHelper::SharedHash['seminar'][:counter][seminar_id]
        if signup_count.nil?
          signup_count = SeminarSignup.where(:seminar_main_id=>self.id).count
          OrbitHelper::SharedHash['seminar'][:counter][seminar_id] = signup_count
        end
      end
    else
      signup_count = SeminarSignup.where(:seminar_main_id=>self.id).count
    end
    return (tmp_signup_limit <= signup_count)
  end
  def self.time_range(date1 = null, date2 = null)

    if !date1.blank?

      r = "#{date1.strftime('%Y-%m-%d')}"

      if date2
        r += " - #{date2.strftime('%Y-%m-%d')}" 
      else
        r += " - #{I18n.t(:no_deadline)}"
      end

      r

    end

  end
  def manage_announcement_count(num)
    if defined?(@@in_use_locales).nil?
      @@in_use_locales = Site.first.in_use_locales.map{|l| l.to_s}
    end
    self.annc_count += num
    home_page = Page.where(:parent_page_id=>self.id).first
    page_part = home_page.page_parts.where(:part_id=>annc_part_id).first
    if self.annc_count <= 0
      if page_part
        page_part.sub_parts.where(kind: "module_widget",module: "custom_announcement").destroy
      end
      self.annc_count = 0
      home_page.find_page(:page_id=>"news").update_all(:enabled_for=>[],:enabled_for_mobile=>false,:menu_enabled_for => [])
    else
      if page_part.nil?
        page_part = home_page.page_parts.create(:part_id=>annc_part_id)
      end
      if page_part.sub_parts.where(kind: "module_widget",module: "custom_announcement").count == 0
        sub_part = page_part.sub_parts.create(kind: "module_widget",module: "custom_announcement",
          title_translations: {"zh_tw"=>"公告", "en"=>"News"},read_more_page_id: "news",
          widget_type: "annc_widget11",widget_method:  "widget",
          data_count: annc_data_count,custom_data_field: {"bind_module_app"=>"seminar", "bind_uid"=>self.uid})
        sub_part.select_options.create(annc_default_select_option_attr)
      end
      home_page.find_page(:page_id=>"news").update_all(:enabled_for=>@@in_use_locales,:enabled_for_mobile=>true,:menu_enabled_for => @@in_use_locales)
    end
    self.save
  end
  def annc_default_select_option_attr
    module_app = ModuleApp.where(:key=>'custom_announcement').first
    field_name = module_app.show_option_keys.first.all[2].to_s
    value = module_app.show_option_values.first.all[2][3].to_yaml
    return {field_name: field_name, value: value}
  end
  def annc_data_count
    self.seminar_template_setting.announcement_limit rescue 4
  end
  def album_data_count
    self.seminar_template_setting.album_limit rescue 4
  end
  def annc_part_id
    200
  end
  def album_part_id
    201
  end
  def manage_album_count(num)
    if defined?(@@in_use_locales).nil?
      @@in_use_locales = Site.first.in_use_locales.map{|l| l.to_s}
    end
    self.album_count += num
    home_page = Page.where(:parent_page_id=>self.id).first
    page_part = home_page.page_parts.where(:part_id=>album_part_id).first
    if self.annc_count <= 0
      if page_part
        page_part.sub_parts.where(kind: "module_widget",module: "custom_gallery").destroy
      end
      home_page.find_page(:page_id=>"album").update_all(:enabled_for=>[],:enabled_for_mobile=>false,:menu_enabled_for => [])
      self.annc_count = 0
    else
      if page_part.nil?
        page_part = home_page.page_parts.create(:part_id=>annc_part_id)
      end
      if page_part.sub_parts.where(kind: "module_widget",module: "custom_gallery").count == 0
        page_part.sub_parts.create(kind: "module_widget",module: "custom_gallery",
          title_translations: {"zh_tw"=>"相簿", "en"=>"Album"},read_more_page_id: "album",
          widget_type: "custom_gallery_widget2",widget_method:  "widget",
          data_count: album_data_count,custom_data_field: {"bind_module_app"=>"seminar", "bind_uid"=>self.uid})
      end
      home_page.find_page(:page_id=>"album").update_all(:enabled_for=>@@in_use_locales,:enabled_for_mobile=>true,:menu_enabled_for => @@in_use_locales)
    end
    self.save
  end
  def get_attribute_value(attribute_field, signup_id)
      SeminarSignupValue.find_by(seminar_signup_field_id: attribute_field.id, seminar_signup_id: signup_id)
  end

  def get_attribute_values(attribute_type=nil)
      @attribute_values = attribute_type.seminar_signup_values rescue nil
  end
  
  def get_value_from_field_id(field_id,attribute_type=nil)
      values = get_attribute_values(attribute_type)
      value = values.detect {|value| value.seminar_signup_field_id == field_id} rescue nil
      value ? value : nil
  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
    seminar,clone_target = clone_new_for_object(self,clone_target,clone_mode)
    if clone_mode
      copy_settings = SeminarSignupAdminSetting.where(:seminar_main_id=>clone_target.id.to_s).to_a
      copy_settings.each do |setting|
        new_setting = setting.dup
        new_setting.seminar_main_id = seminar.id.to_s
        new_setting.save
      end
      count_array = (0...self.seminar_sessions.to_a.count).to_a
      count_array.each do |i|
        seminar_session = self.seminar_sessions[i]
        seminar_session.seminar_signup_ids = map_seminar_signup_ids(seminar_session.seminar_signup_ids)
      end
      self.unassigned_seminar_signup_ids = map_seminar_signup_ids(clone_target.unassigned_seminar_signup_ids)
      self.unassigned_mode_1_seminar_signup_ids = map_seminar_signup_ids(clone_target.unassigned_mode_1_seminar_signup_ids)

      need_change_seminar_signups = self.seminar_signups.where(:seminar_session_ids.nin=>[nil,[]]).to_a
      count_array = (0...need_change_seminar_signups.count).to_a
      count_array.each do |i|
        seminar_signup = need_change_seminar_signups[i]
        if seminar_signup.seminar_session_ids.present?
          seminar_signup.seminar_session_ids = seminar_signup.seminar_session_ids.map{|id| @records_all["seminar_session_ids"][id]} rescue []
        end 
      end
      count_array = (0...self.seminar_reviews.to_a.count).to_a
      change_fields = [:seminar_signup_ids, :remove_seminar_signup_ids, :default_seminar_signup_ids]
      count_array.each do |i|
        seminar_review = self.seminar_reviews[i]
        change_fields.each do |f|
          seminar_review.send("#{f}=",map_seminar_signup_ids( seminar_review.send(f)))
        end
        seminar_review.seminar_session_ids = seminar_review.seminar_session_ids.map{|seminar_session_id| @records_all["seminar_session_ids"][seminar_session_id] rescue nil}.select{|id| !id.nil?}
        seminar_review.default_topics = seminar_review.default_topics.map do |default_topic|
          fn,id = default_topic.split(".")
          if fn == "seminar_signup_fields"
            id = @records_all["seminar_signup_field_ids"][BSON::ObjectId(id)].to_s rescue nil
          elsif fn == "seminar_submission_fields"
            id = @records_all["seminar_submission_field_ids"][BSON::ObjectId(id)].to_s rescue nil
          end
          "#{fn}.#{id}"
        end
      end
    end
    seminar
  end
  def map_seminar_signup_ids(old_seminar_signup_ids)
    if @records_all["seminar_signup_ids"].present?
      old_seminar_signup_ids.map{|seminar_signup_id| @records_all["seminar_signup_ids"][BSON::ObjectId(seminar_signup_id)].to_s rescue ""}.select{|t| t.present?}
    else
      []
    end
  end
  def clone_new_for_object(object,clone_target=nil,clone_mode=false)
    @except_clone_relations ||= self.except_clone_relations
    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 @except_clone_relations.to_s.include?(new_object.class.to_s.underscore)
    @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?
      if clone_mode
        initialize_fields = []
        if new_object.fields.keys.include?("uid")
          new_object.generate_uid
        end
      else
        initialize_fields = ["uid","created_at","updated_at"]
      end
      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
      unless @parent_level
        unsort_relation_keys = clone_target.relations.keys
        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.to_s.start_with?('has') }.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
                org_k = k.to_s
                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.to_s.start_with?('has') }.keys
                  if (belongs_to_class - tmp_singularize_relations_fields - [org_k]).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
          relations_fields -= @relations_fields if @relations_fields
        end
        relations_fields = tmp_relations_fields
        fields_to_delete.each{|f| relations_fields.delete(f)}
      end
      if @parent_level
        relations_fields -= @relations_fields
      else
        @clone_mode = clone_mode
        @relations_fields = relations_fields
      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 || clone_target.relations[f].macro == :has_and_belongs_to_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 @except_clone_relations.to_s.include?(f)
          need_clone_relation = clone_target.send(f)
          clone_relation = new_object.send(f)
          clone_relation, need_clone_relation = clone_new_for_object(need_clone_relation.dup, need_clone_relation, true) 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 || clone_target.relations[f].macro == :has_and_belongs_to_many
          next if @except_clone_relations.to_s.include?(f)
          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
            new_object_relations_count = new_object_relations.count
            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
  def fix_old_data
    unless self.update_old_flag
      self.seminar_signups.each do |ss|
        ss.final_sessions = Array(ss.final_session)
        ss.seminar_session_ids = Array(ss.seminar_session_id)
        if ss.final_session
          ss.seminar_signup_contributes.update_all(:final_session=>final_session)
          SeminarSubmissionValue.where(:seminar_signup_contribute_id.in=> ss.seminar_signup_contributes.pluck(:id)).each{|ssv| ssv.save}
        end
        ss.save
      end
      self.seminar_sessions.each{|ss| ss.fix_seminar_signup_contribute_ids}
      self.update(:update_old_flag=>true)
    end
  end
  def enable_custom_template
    self.seminar_template_setting && self.seminar_template_setting.enable_custom_template
  end
  def enable_review_result
    self.assign_mode == 2
  end
end