require 'time' require 'date' class Event include Mongoid::Document include Mongoid::Timestamps include OrbitTag::Taggable # include Mongoid::MultiParameterAttributes field :title field :note field :title_translations,type: Hash,default: {} field :note_translations,type: Hash,default: {} field :start, type: DateTime field :end, type: DateTime field :all_day, type: Boolean,default: false field :recurring, type: Boolean,default: false field :frequency field :period field :create_user_id field :update_user_id field :module_key field :model_cat field :model_page_id field :model_tags,type: Array,default: [] belongs_to :calendar_type field :url def get_module_url page = !self.model_page_id.blank? ? Page.find(self.model_page_id): Page.where(:module => self.module_key).where(:categories.in => Array(self.model_cat)+[[]],:tags.in=>Array(self.model_tags)+[[]]).first page.nil? ? '' : (page.url+'/'+eval(self.model_class).where(:id=>self.model_id).first.to_calendar_param) end def url_to_fronted self.url.blank? ? (self.model_class.blank? ? '' : self.get_module_url) : self.url end attr_accessor :agenda_start, :agenda_end, :get_agenda_events #let other model can connect to this model field :key field :model_class field :model_id before_destroy do if !self.model_class.blank? m = eval(self.model_class).where(id: self.model_id).first rescue nil if !m.nil? if self.key.nil? m.event_id = nil m.add_to_calendar = false else m.calendar_dict.delete(self.key) if !m['calendar_data'].nil? tmp = m['calendar_data'] tmp['key'] = Array(tmp['key']) - [self.key] m['calendar_data'] = tmp end end m.save end end end ######################################## validates_presence_of :title, :message => "Please fill the title of the Event", :if => lambda { self['title_translations'].blank? } validates_presence_of :title_translations, :message => "Please fill the title of the Event", :if => lambda { self['title'].blank? } def title tp = self['title_translations'][I18n.locale] rescue nil tp.blank? ? self['title'] : tp end def note tp = self['note_translations'][I18n.locale] tp.blank? ? self['note'] : tp end def self.with_categories(cat_ids=[]) if cat_ids.blank? self.all else type_ids = CalendarType.where(:category_id.in=>cat_ids).pluck(:id) self.where(:calendar_type_id.in => type_ids) end end def bulletin model_class=='Bulletin' ? (Bulletin.find(self.model_id) rescue nil) : nil end def self.format_date(date_time) Time.at(date_time.to_i).to_formatted_s(:db) end REPEATS = [ "Daily" , "Weekly" , "Monthly" , "Yearly" ] def as_json(options = {}) if options["frontend"] { :id => self.id.to_s, :title => self.title, :note => self.note || "", :start => self.start.rfc822, :end => self.end.rfc822, :allDay => self.all_day, :recurring => self.recurring, :calendar => self.calendar_type_id.to_s, :color => (self.calendar_type.color rescue nil) } else { :id => self.id.to_s, :title => self.title, :note => self.note || "", :start => self.start.rfc822, :end => self.end.rfc822, :allDay => self.all_day, :recurring => self.recurring, :calendar => self.calendar_type_id.to_s, :color => (self.calendar_type.color rescue nil), :edit_url => Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>self.id), :delete_url => Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>self.id) } end end def self.monthly_event(start_date,end_date) self.any_of({:start.lte => start_date,:end.gte => start_date},{:start.gte => start_date,:end.lte => end_date},{:start.lte => end_date,:end.gte => end_date}).asc(:start) end def self.convert_front self.all.collect do |re| edit_url = Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>re.id) delete_url = Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>re.id) {:id => re.id.to_s, :title=>re.title, :note=>re.note || "", :allDay => re.all_day, :recurring => re.recurring, :calendar => re.calendar_type.id.to_s, :color => re.calendar_type.color, :edit_url => edit_url, :delete_url => delete_url, :url_linked => re.url_to_fronted, :start => re.start, :end => re.end} end end def self.get_diff_month(date1,date2) (date2.year-date1.year)*12+(date2.month-date1.month) end def self.recurring_event(start_date,end_date) @recurring_events = self.where(:recurring => true) @recurring = [] @recurring_events.each do |re| edit_url = Rails.application.routes.url_helpers.edit_admin_calendar_path(:locale=>I18n.locale, :id=>re.id) delete_url = Rails.application.routes.url_helpers.admin_calendar_path(:locale=>I18n.locale, :id=>re.id) data = {:id => re.id.to_s, :title=>re.title, :note=>re.note || "", :allDay => re.all_day, :recurring => re.recurring, :calendar => re.calendar_type.id.to_s, :color => re.calendar_type.color, :edit_url => edit_url, :delete_url => delete_url, :url_linked => re.url_to_fronted} case re.period when 'Daily' days = (end_date.to_date-re.start.to_date).to_i freq = re.frequency.to_i start_key = (start_date.to_date-re.start.to_date).to_i start_key = 1 if start_key<0 (start_key..days).each do |i| if i%freq==0 @start_date = re.start + i @end_date = re.end + i @recurring << data.merge({:start => @start_date, :end => @end_date}) end end when "Weekly" @start_date = re.start @edn_date = re.end @i = TimeDifference.between(re.start.to_date,end_date.to_date).in_weeks.to_i (1..@i).each do |i| @start_date += (7*re.frequency.to_i) @end_date += (7*re.frequency.to_i) @recurring << data.merge({:start => @start_date, :end => @end_date}) end when "Monthly" if !(start_date..end_date).cover?(re.start) && start_date.to_datetime>re.start sd = re.start ed = re.end end_datetime = end_date.to_datetime start_datetime = start_date.to_datetime months = self.get_diff_month(sd,start_datetime)..self.get_diff_month(sd,end_datetime) months.each do |diff_month| if (diff_month%re.frequency.to_i)==0 sd_tp = sd + diff_month.month ed_tp = ed + diff_month.month if sd_tp>start_date @recurring << data.merge({:start => sd_tp, :end => ed_tp}) end end end end when "Yearly" if !(start_date..end_date).cover?(re.start) sd = re.start ed = re.end start_datetime = start_date.to_datetime end_datetime = end_date.to_datetime if start_datetime>sd && start_datetime.year != sd.year ((start_datetime.year-sd.year)..(end_datetime.year-sd.year)).each do |year_diff| if (year_diff%re.frequency.to_i)==0 sd_tp = sd + year_diff.year ed_tp = ed + year_diff.year @recurring << data.merge({:start => sd_tp, :end => ed_tp}) end end end end end end @recurring end def self.agenda_events(agenda_start, agenda_end) recurring = self.recurring_event(agenda_start,agenda_end) events = self.monthly_event(agenda_start, agenda_end).convert_front all_events = recurring.concat(events) recurring end end