Skip to content

Instantly share code, notes, and snippets.

@andrius
Created February 22, 2013 22:34
Show Gist options
  • Save andrius/5017092 to your computer and use it in GitHub Desktop.
Save andrius/5017092 to your computer and use it in GitHub Desktop.
Business time management for Ruby application Say, application need to manage time flexible, what do you think about this implementation?
# Migration
create_table :business_time_members do |t|
t.string :name, :limit => 100
t.integer :business_time_id
t.time :time_from, :default => '2000-01-01 00:00:00'
t.time :time_to, :default => '2000-01-01 23:59:59'
t.integer :weekday # 0 - sunday, 1 - monday, 2 -tuesday, ...
t.integer :day_of_month # 1-31
t.integer :month # 1-12
t.integer :year # 2012
t.integer :item_id, :default => 0 # item with action!
t.timestamps
end
create_table :business_times do |t|
t.string :name, :limit => 100
t.timestamps
end
execute "INSERT INTO `business_times` (`id`, `name`)
VALUES (1, 'Call Mon-Fri 9 to 21; Sat, Sun 11 to 19')"
# Always closed!
# It is a default condition with lowest priority and will be executed it other conditions did not met.
# BusinessTimeMember.create :business_time => business_time, :item => closed_action
execute "INSERT INTO `business_time_members` (`id`, `business_time_id`, `item_id`) VALUES (?, 1, NULL)"
# Make calls on business days (Monday to Friday) from 9:00 to 21:00,
# on weekends (Sunday and Saturday) from 11:00 to 19:00
# 0 - Sun, 6 - Sat
0.upto(6) do |day|
time_from, time_to = if day == 0 || day == 6 then
#[Time.parse("11:00:00"), Time.parse("18:59:59")]
[Time.parse("00:00:00"), Time.parse("23:59:59")]
else
#[Time.parse("9:00:00"), Time.parse("20:59:59")]
[Time.parse("00:00:00"), Time.parse("23:59:59")]
end
# item_id 0 = continue dialplan!
# BusinessTimeMember.create :business_time => business_time,
# :item_id => 0, :weekday => day,
# :time_from => "6:00", :time_to => "17:00"
execute "INSERT INTO `business_time_members`
(`id`, `business_time_id`, `weekday`, `time_from`, `time_to`, `item_id`)
VALUES (?, 1, #{day}, '#{time_from}', '#{time_to}', 0)"
end
# Model
class BusinessTimeMember < ActiveRecord::Base
#validations
validates_presence_of :business_time_id
validates_presence_of :item_id
# 0 (zero) means to continue dialplan after check!
validates_numericality_of :item_id #, :greater_than => 0
# relations
belongs_to :business_time
belongs_to :item
end
class BusinessTime < ActiveRecord::Base
has_many :business_time_members, :dependent => :destroy
has_many :items, :as => :routable
has_many :soho_pbxes
# return false if no records found,
# 0 if specified - means "continue" dialplan,
# or item_id
def operational?(details = { :datetime => Time.now.utc })
d = details[:datetime]
=begin
if self.timezone
begin
tz = TZInfo::Timezone.get(self.timezone)
local = tz.utc_to_local(d)
puts "got timezone #{self.timezone} - utc #{d}, local #{local}"
d = local
rescue
puts "got exception for timezone #{self.timezone}"
end
end
=end
tm = BusinessTimeMember.find(
:all,
:conditions => { :business_time_id => id },
:order => "
business_time_id,
day_of_month desc,
month desc,
year desc,
weekday desc,
time_from desc,
time_to asc
"
)
return false if tm.empty?
tm.each { |t|
tf = t[:time_from] ? Time.parse(t[:time_from].strftime("%H:%M:%S")) : Time.parse("00:00:00")
tt = t[:time_to] ? Time.parse(t[:time_to].strftime("%H:%M:%S")) : Time.parse("23:59:59")
tw = t[:weekday] ? t[:weekday].to_i : d.wday
td = t[:day_of_month] ? t[:day_of_month].to_i : d.day
tm = t[:month] ? t[:month].to_i : d.month
ty = t[:year] ? t[:year].to_i : d.year
if ty == d.year && tm == d.month && td == d.day && tw == d.wday && d >= tf && d <= tt then
return t.item_id
end
}
return false
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment