event_news/app/models/event_news.rb

383 lines
14 KiB
Ruby

class EventNews
include Mongoid::Document
include Mongoid::Timestamps
include OrbitModel::Status
include OrbitModel::Impression
# encoding: utf-8
include OrbitTag::Taggable
include OrbitCategory::Categorizable
include Slug
require 'event_news_model/cache'
include EventNewsModel::Cache
attr_accessor :org_tag_ids
def tags=(ids)
self.org_tag_ids = self.tag_ids
super(ids)
end
def []=(index,value)
if index.to_s=='tags'
self.org_tag_ids = self.tag_ids
end
super(index,value)
end
SubPart.class_eval { include EventNewsModel::Cache }
Page.class_eval { include EventNewsModel::Cache }
before_destroy do
EventNewsCache.all.destroy
end
Week_day_trans = {:en=>["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
:zh_tw=>["(日)","(一)","(二)","(三)","(四)","(五)","(六)"]}
field :event_date_use_default_setting, type: Boolean, default: true
field :including_day_of_the_week, type: Boolean, default: true
field :including_time, type: Boolean, default: true
field :hour_clock_24, type: Boolean, default: true
field :is_edit, type: Boolean, default: false #use to check whether the preview record changed
field :copy_id
field :custom_carousel_image_width, type: String, default: ""
field :image_display_class, type: String, default: "full-size-img" #3 choices: full-size-img , pull-left , pull-right
field :add_to_calendar,type: Boolean,default: false
field :calendar_start_date, :type => DateTime
field :calendar_end_date, :type => DateTime
field :calendar_all_day,type: Boolean,default: false
field :all_day,type: Boolean,default: false #old field
field :calendar_type_id
field :event_id
field :place, type: String, localize: true
field :title, as: :slug_title, type: String, localize: true
field :speaker, type: String, localize: true
field :host, type: String, localize: true
field :subtitle, localize: true
field :text, localize: true, default: ''
field :notes, localize: true
field :create_user_id
field :update_user_id
field :public, :type => Boolean, :default => true
field :event_date , :type => DateTime, :default => Time.now
field :event_end_date , :type => DateTime
field :postdate , :type => DateTime, :default => Time.now
field :deadline , :type => DateTime
field :rss2_sn
field :approved, :type => Boolean, :default => false
field :is_preview, :type => Boolean, :default => false
field :expirable_created_at, type: DateTime
field :rejected, :type => Boolean, :default => false
field :reapproval, :type => Boolean, :default => false
field :rejection_reason
field :is_external_link, :type => Boolean, :default => false
field :external_link
field :display_subtitle, :type => Boolean, :default => false
field :display_img, :type => Boolean, :default => false
field :email_id
field :email_sent, :type => Boolean, :default => false
field :email_sentdate , :type => DateTime
field :email_member_ids
field :other_mailaddress
field :image_description, localize: true
field :top_end_date, :type => DateTime
mount_uploader :image, ImageUploader
has_many :event_news_links, :autosave => true, :dependent => :destroy
has_many :event_news_files, :autosave => true, :dependent => :destroy
has_many :event_carousel_images, :autosave => true, :dependent => :destroy
accepts_nested_attributes_for :event_news_files, :allow_destroy => true
accepts_nested_attributes_for :event_news_links, :allow_destroy => true
accepts_nested_attributes_for :event_carousel_images, :allow_destroy => true
before_destroy :destroy_email
scope :open_in_future, ->{where(:is_hidden.ne=>true,:is_preview.ne => true,:postdate.gt=>Time.now).order(postdate: :asc)}
scope :can_display_and_sorted, ->{where(:is_hidden.ne=>true,:is_preview.ne => true).valid_time_range.order(event_date: :desc)}
scope :can_display_and_sorted_according_today, ->{where(:is_hidden.ne=>true,:is_preview.ne => true).order(event_date: :asc).valid_time_range.where(:event_date.gte => Date.today.to_time)}
scope :valid_time_range, ->{and_any_of([{"postdate"=>{"$lte"=> Time.now}, "deadline"=>{"$gte"=> Time.now}}, {"postdate"=>{"$lte"=> Time.now}, "deadline"=>nil}]).order((@manually_sort ? {is_top: :desc,sort_number: :asc,postdate: :desc,id: :desc} : {is_top: :desc,postdate: :desc,id: :desc}))}
scope :is_approved, ->{where(:approved => true)}
scope :is_approved_and_show, ->{where(:approved => true,:is_hidden.ne=>true,:is_preview.ne => true)}
scope :filter_cats_and_tags, ->(cats,tags) {filter_by_widget_categories(cats,false).filter_by_tags(tags)}
before_create :set_expire
before_save :check_limit
before_save do
if @is_hidden_changed.nil? || @is_hidden_changed != true
@is_hidden_changed = self.is_hidden_changed?
end
if self.is_top_changed? && !self.is_top
self.sort_number = nil
end
end
index({postdate: 1}, { unique: false, background: true })
index({is_top: -1, postdate: -1, event_date: -1, _id: -1}, { unique: false, background: true })
index({is_top: -1, event_date: 1, postdate: -1, _id: -1}, { unique: false, background: true })
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, event_date: 1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
if EventNewsSetting.pluck(:enable_manually_sort).first == true
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, sort_number: 1, postdate: -1, event_date: -1, _id: -1, deadline: -1}, { unique: false, background: true })
index({approved: -1, is_hidden: 1, is_preview: 1, is_top: -1, sort_number: 1, event_date: 1, postdate: -1, _id: -1, deadline: -1}, { unique: false, background: true })
end
field :sort_number, type: Integer
def get_org_model
if self.is_preview
org_model = nil
if self.copy_id
org_model = self.class.find(self.copy_id) rescue nil
else
org_model = self.class.where(:title=>self.title,:is_preview.ne=>true).desc(:updated_at).first
end
org_model.nil? ? self : org_model
else
self
end
end
def date_parse_format
#all_day ? '%Y-%m-%d' : '%Y-%m-%d %H:%M'
event_date_format
end
def get_weekday(w)
trans = self.class::Week_day_trans
if trans.keys.include?(I18n.locale)
trans[I18n.locale][w]
else
trans[:en][w]
end
end
def event_date_format
@event_date_format ||= (self.event_date_use_default_setting ? EventNewsSetting.event_date_default_format : self.event_date_custom_format)
end
def event_date_custom_format
datetime_format = "%Y-%m-%d"
if self.including_day_of_the_week
datetime_format += " %a"
end
if self.including_time
if self.hour_clock_24
datetime_format += " %H:%M"
else
datetime_format += " %I:%M %P"
end
end
datetime_format
end
def custom_strftime(dt, datetime_format)
if dt
dt.strftime(datetime_format.sub("%a","%%a")).sub("%a",get_weekday(dt.wday))
else
""
end
end
def event_time_formated_for_frontend
st,ed = self.event_time_formated.split("~")
if st.nil?
st = ""
else
st = "<span class=\"start_date\">#{st}</span>"
end
if ed.nil?
st
else
ed = "<span class=\"start_date\">#{ed}</span>"
"#{st} ~ #{ed}"
end
end
def event_date_frontend
s = self.event_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
if s.blank?
""
else
parse_format = self.date_parse_format
custom_strftime(s, self.date_parse_format)
end
end
def event_end_date_frontend
e = self.event_end_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
if e.blank?
""
else
parse_format = self.date_parse_format
custom_strftime(e, self.date_parse_format)
end
end
def event_time_formated
s = self.event_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
e = self.event_end_date.in_time_zone(Time.zone.utc_offset / 3600) rescue nil
if s.blank? && e.blank?
""
elsif e.blank?
custom_strftime(s, self.date_parse_format)
elsif s.blank?
"~ " + custom_strftime(e, self.date_parse_format)
else
parse_format = self.date_parse_format
if s.to_date == e.to_date
parse_format_arr = parse_format.split(/(%d %a|%d) /)
if parse_format_arr.count > 1
parse_format_arr = parse_format_arr[0..-2].join(""), parse_format_arr[-1]
end
date_str = custom_strftime(s, parse_format_arr[0])
s_time = s.strftime(parse_format_arr[1].to_s)
e_time = e.strftime(parse_format_arr[1].to_s)
if e_time.present?
if s_time != e_time
"#{date_str} #{s_time} ~ #{e_time}"
else
"#{date_str} #{s_time}"
end
else
date_str
end
else
custom_strftime(s, self.date_parse_format) + " ~ " + custom_strftime(e, self.date_parse_format)
end
end
end
def to_calendar_param
self.to_param
end
def calendar_type
CalendarType.where(:category_id.in => self.calendar_type_id)
end
def event
if !self.event_id.nil?
Event.where(:id => self.event_id).first
else
nil
end
end
def check_limit
check_status_limit(update_user)
end
def check_status_limit(user,check_only=false)
role_ids = user.member_profile.roles.map(&:id) rescue []
status_settings = (role_ids.collect do |role_id|
EventNewsSetting.first.event_news_status_settings.select{|v| v.role_id.to_s == role_id.to_s}
end.flatten rescue [])
reach_limit = []
if status_settings.count != 0
reach_limit = status_settings.collect do |status_setting|
status = status_setting.status
if status_setting.top_limit.to_i <= self.class.where(:is_preview.ne=>true,:update_user_id.in => Role.find(status_setting.role_id).member_profiles.collect(&:user).flatten.uniq.map{|v| v.id},status => true).count
if !check_only
if self[status] && !self.class.where(id:self.id).first[status]
self[status] = false
nil
end
else
status
end
else
nil
end
end.compact
reach_limit = reach_limit.group_by{|v| v}.collect do |k,v|
if v.count >= user.member_profile.roles.count
k
else
nil
end
end.compact
end
reach_limit
end
def set_expire
self.expirable_created_at = Time.now if self.is_preview
return true
end
def update_user
User.find(update_user_id) rescue nil
end
def update_user=(user)
self.update_user_id = user.id
end
def email_members
MemberProfile.find(self.email_member_ids) rescue []
end
def email_addresses
addresses = self.email_members.collect{|member| member.email} rescue []
addresses = addresses +[self.other_mailaddress] if !self.other_mailaddress.blank?
addresses.flatten
end
def email
mail = Email.find(self.email_id) rescue nil
end
def expired?
(self.deadline < Time.now) rescue false
end
def destroy_email
mail = Email.find(self.email_id) rescue nil
mail.destroy if !mail.nil?
end
def self.remove_expired_status
self.where(:is_top => true, :top_end_date.ne => nil, :top_end_date.lt => Time.now).each do |b|
b.is_top = false
b.top_end_date = nil
b.save
end
end
def display_subtitle?
self.display_subtitle rescue false
end
def display_img?
self.display_img rescue false
end
def statuses
statuses = []
statuses << top_text if is_top?
statuses << hot_text if is_hot?
statuses << hidden_text if is_hidden?
statuses
end
def statuses_with_classname
statuses = []
statuses << {"name" => top_text, "classname" => "top"} if is_top?
statuses << {"name" => hot_text, "classname" => "hot"} if is_hot?
statuses << {"name" => hidden_text, "classname" => "hidden"} if is_hidden?
statuses
end
def status_for_table
status = ""
status << "<span class='label label-success'>#{top_text}</span> " if self.is_top
status << "<span class='label label-important'>#{hot_text}</span> " if self.is_hot
status << "<span class='label'>#{hidden_text}</span>"if self.is_hidden
status.html_safe
end
def top_text
I18n.t("announcement.status.top")
end
def hot_text
I18n.t("announcement.status.hot")
end
def hidden_text
I18n.t("announcement.status.hidden")
end
def carousel_image_width
(self.custom_carousel_image_width.blank? ? AnnouncementSetting.last.carousel_image_width : self.custom_carousel_image_width)
end
def self.agenda_events(agenda_start, agenda_end,read_more_url)
events = self.monthly_event(agenda_start, agenda_end).convert_front(read_more_url)
end
def self.monthly_event(start_date,end_date)
self.any_of({:event_date.lte => start_date,:event_end_date.gte => start_date},{:event_date.gte => start_date,:event_end_date.lte => end_date},{:event_date.lte => end_date,:event_end_date.gte => end_date}).asc(:event_date)
end
def self.convert_front(read_more_url)
self.all.collect do |re|
{:id => re.id.to_s,
:title=>re.title,
:note=>re.subtitle || "",
:allDay => false,
:color => nil,
:url_linked => (re.is_external_link ? re.external_link : "#{read_more_url}/#{re.to_param}" rescue ""),
:start => re.event_date,
:end => re.event_end_date}
end
end
end