class PHire include Mongoid::Document include Mongoid::Timestamps INTERVALS = ["week", "month"] field :date, type: Date field :start_time, type: DateTime field :end_time, type: DateTime field :hiring_person_email field :hiring_person_number field :hiring_person_id field :hiring_person_name field :reason_for_hire field :tmp_reason_for_hire, type: String, default: "" # store reason text from custom fields field :note_for_hire field :property_day_setting_id field :passed, type: Boolean, default: false field :recurring, type: Boolean, :default => false field :recurring_end_date, type: DateTime field :recurring_interval field :organization field :person_in_charge field :tel_of_person_in_charge field :department field :contact_person field :tel_of_contact_person field :mobile_phone_of_contact_person field :contact_person_Email field :contact_person_department belongs_to :property has_many :p_hire_field_values, :autosave => true, :dependent => :destroy accepts_nested_attributes_for :p_hire_field_values, allow_destroy: true def property_day_setting PropertyDaySetting.find(self.property_day_setting_id) rescue nil end def time property_day_setting.title rescue nil end def as_json(options = {}) startt = self.start_time endt = self.end_time recurring = false datet = self.date if options[:startt] startt = options[:startt] end if options[:endt] endt = options[:endt] end if options[:datet] datet = options[:datet] end if options[:recurring] recurring = options[:recurring] end { :id => self.id.to_s, :title => (self.reason_for_hire.to_s + " "+ self.tmp_reason_for_hire.to_s).html_safe, :hiring_person_id => self.hiring_person_id, :hiring_person_name => self.hiring_person_name, :note => self.note_for_hire || "", :start => startt.to_json.gsub('"',''), :end => endt.to_json.gsub('"',''), :allDay => false, :diff_day => (self.end_time - self.start_time >= 1), :color => (self.passed ? "#3788d8" : "#FC4040"), :error_message => (self.passed ? nil : "Not approved"), :s_id=>self.property_day_setting_id.to_s, :date=>datet, :recurring=>recurring } end def period return self.start_time.strftime("%y-%m-%d %H:%M") + " ~ " + self.end_time.strftime("%y-%m-%d %H:%M") end def hirer_name return self.hiring_person_name.nil? ? (self.hiring_person_profile.name rescue "") : self.hiring_person_name end def hiring_person_profile return MemberProfile.find(self.hiring_person_id) rescue nil end def self.monthly_event(start_date,end_date,property_id,date_only=false) events = self.where(:property_id => property_id, :recurring => false).any_of([{:start_time.gte => start_date}, {:end_time.gte => start_date}]).and(:start_time.lte => end_date).asc(:start_time) if date_only events = events.where(:date.ne=>nil) end events end def self.convert_datetime(time) if time.class == Time return time.to_datetime elsif time.class == DateTime return time elsif time.class == String return DateTime.parse(time) else return Time.at(time).to_datetime #time is seconds end end def self.recurring_event(start_date,end_date,property_id,date_only=false) start_date = convert_datetime(start_date) end_date = convert_datetime(end_date) @property = Property.find(property_id) rescue nil @recurring = [] if @property != nil unavailable = @property.set_unavailibility && !@property.weekdays.empty? && !@property.start_date.nil? && !@property.end_date.nil? unavailable_start_date = @property.start_date unavailable_end_date = @property.end_date unavailable_start_time = @property.start_time.to_s unavailable_end_time = @property.end_time.to_s unavailable_start_date = DateTime.parse(unavailable_start_date.strftime("%Y-%m-%d " + unavailable_start_time.to_s + Time.zone.to_s)) rescue nil unavailable_end_date = DateTime.parse(unavailable_end_date.strftime("%Y-%m-%d " + unavailable_end_time.to_s + Time.zone.to_s)) rescue nil unavailable_weekdays = @property.weekdays.collect{|w| w.to_i} @recurring_events = self.where(:property_id => property_id, :recurring_end_date.gte => start_date) if date_only @recurring_events = @recurring_events.where(:date.ne=>nil) end @recurring_events.each do |re| datet = re.date interval = 1.send(re.recurring_interval) rescue 0 if interval != 0 @start_date = re.start_time recurring_end_date = re.recurring_end_date new_end_date = [recurring_end_date,end_date].min @end_date = re.end_time if @start_date < start_date add_interval = nil if re.recurring_interval == "week" add_interval = ((start_date - @start_date).to_i / 7).send("week") else add_interval = ((start_date.year * 12 + start_date.month) - (@start_date.year * 12 + @start_date.month) - 1).send("month") end @start_date += add_interval @end_date += add_interval end while @start_date <= new_end_date do if unavailable && (unavailable_start_date <= @start_date) && (unavailable_end_date >= @end_date) && !((@start_date.strftime("%w").to_i .. @end_date.strftime("%w").to_i).to_a & unavailable_weekdays).empty? startt = DateTime.parse(@start_date.strftime("%Y-%m-%d " + unavailable_start_time + Time.zone.to_s)) endt = DateTime.parse(@end_date.strftime("%Y-%m-%d " + unavailable_end_time + Time.zone.to_s)) if !((startt..endt) & (@start_date..@end_date)).blank? @start_date += interval @end_date += interval datet += interval if datet next end end if @start_date >= start_date @recurring << re.as_json({:startt=>@start_date,:endt=>@end_date,:datet=>datet}) end @start_date += interval @end_date += interval datet += interval if datet end end end end @recurring end def time_iterate(&block) start_time = self.start_time end_time = self.end_time recurring_end_date = self.recurring_end_date case self.recurring_interval when "week" step_interval = 1.week when "month" step_interval = 1.month end begin yield(start_time, end_time) end_time += step_interval end while (start_time += step_interval) <= recurring_end_date end end