Created
February 22, 2013 22:34
-
-
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?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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