class RulingTimerSubTask include Mongoid::Document include Mongoid::Timestamps field :task_name, type: String, default: "" field :work_time_str, type: String, default: "00:00:00" field :all_work_times_seconds, type: Integer, default: 0 field :work_times, type: Array, default: [] field :status, type: String, default: "stop" # stop, working, finish field :time_offset, type: String, default: "+8" belongs_to :ruling_timer_task belongs_to :user after_destroy do |record| id = record.id.to_s timers = RulingTimerTemp.where(:sub_task_ids=>id).to_a + RulingTimerHistory.where(:sub_task_ids=>id).to_a timers.each do |timer| timer.remove_task(id) end end after_save do |record| if record.task_name_changed? id = record.id.to_s timers = RulingTimerTemp.where(:sub_task_ids=>id).to_a + RulingTimerHistory.where(:sub_task_ids=>id).to_a timers.each do |timer| timer.update_task_name(id,record.task_name) end end end def get_work_times(display_seond=false) work_times = self.work_times.clone if display_seond time_format = "%Y/%m/%d %H:%M:%S" else time_format = "%Y/%m/%d %H:%M" end work_times.map!{|t| convert_datetime(t).new_offset(self.time_offset).strftime(time_format)} end def start(offset="+8") self.time_offset = offset self.status = "working" time_now = DateTime.now.utc if self.work_times.count % 2 == 0 self.work_times.push(time_now) end self.calc("work_times",false) self.save self.ruling_timer_task.update(:is_finished => false) return self.to_json end def reset_all(except_fields=[]) unless self.new_record? change_fields = self.changes.except(*(except_fields.map{|f| f.to_s})) change_fields.each do |k,v| self.send("#{k}=",v[0]) end end end def stop time_now = DateTime.now.utc if self.work_times.count % 2 == 1 self.work_times.push(time_now) end self.status = "stop" self.calc("work_times",false) self.work_time_str = transform_second_to_time(self.all_work_times_seconds) self.save return self.to_json end def finish time_now = DateTime.now.utc if self.work_times.count % 2 == 1 self.work_times.push(time_now) end self.status = "finish" self.calc("work_times") self.work_time_str = transform_second_to_time(self.all_work_times_seconds) self.save self.ruling_timer_task.update(:is_finished => true) return self.to_json end def recalc_all self.calc("work_times",true,true) self.save return self.to_json end def to_json return {"work" => self.all_work_times_seconds} end def get_infos self.calc("work_times") self.work_time_str = transform_second_to_time(self.all_work_times_seconds) self.reset_all([:work_time_str]) return {"work" => self.work_time_str} end def 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 getPaddedComp(comp) return ((comp.to_i < 10) ? ('0' + comp.to_s) : comp.to_s) end def transform_second_to_time(seconds) hour = 3600 minute = 60 total_hour = getPaddedComp(seconds / hour) rest_seconds = seconds % hour total_minute = getPaddedComp(rest_seconds / minute) total_second = getPaddedComp(rest_seconds % minute) return (total_hour + ":" + total_minute + ":" + total_second) end def calc(field_name,padding=true,recalc=false) time_infos = self.send(field_name).clone rescue [] record_field_name = "all_#{field_name}_seconds" tmp_seconds = self.send(record_field_name) all_seconds = 0 start_index = 0 if !recalc all_seconds = tmp_seconds start_index = time_infos.count - 1 start_index -= (start_index % 2) time_infos = time_infos[start_index..-1].to_a if !(self.send("#{field_name}_changed?")) && time_infos.count != 1 return all_seconds end end time_infos.push(DateTime.now.utc) if (padding && time_infos.count % 2 == 1) time_infos.each_with_index do |t,i| if i % 2 == 0 next_t = time_infos[i+1] if !next_t.nil? all_seconds += ((convert_datetime(next_t) - convert_datetime(t)) * 1.day).round else break end end end self.send("#{record_field_name}=",all_seconds) return all_seconds end end