Added next_run_at attribute to jobs.
This commit is contained in:
parent
563f4d9e1d
commit
96fbc9034e
6 changed files with 449 additions and 30 deletions
|
@ -10,9 +10,10 @@ class App.Job extends App.Model
|
||||||
{ name: 'disable_notiifcation', display: 'Disable Notifications', tag: 'boolean', default: true },
|
{ name: 'disable_notiifcation', display: 'Disable Notifications', tag: 'boolean', default: true },
|
||||||
{ name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true },
|
{ name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true },
|
||||||
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
{ name: 'active', display: 'Active', tag: 'active', default: true },
|
||||||
{ name: 'matching', display: 'Matching', readonly: 1 },
|
{ name: 'matching', display: 'Will process', readonly: 1 },
|
||||||
{ name: 'processed', display: 'Processed', readonly: 1 },
|
{ name: 'processed', display: 'Has processed', readonly: 1 },
|
||||||
{ name: 'last_run_at', display: 'Last run', tag: 'datetime', readonly: 1 },
|
{ name: 'last_run_at', display: 'Last run', tag: 'datetime', readonly: 1 },
|
||||||
|
{ name: 'next_run_at', display: 'Scheduled for', tag: 'datetime', readonly: 1 },
|
||||||
{ name: 'running', display: 'Running', tag: 'boolean', readonly: 1 },
|
{ name: 'running', display: 'Running', tag: 'boolean', readonly: 1 },
|
||||||
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||||
|
@ -23,6 +24,7 @@ class App.Job extends App.Model
|
||||||
@configure_overview = [
|
@configure_overview = [
|
||||||
'name',
|
'name',
|
||||||
'last_run_at',
|
'last_run_at',
|
||||||
'matching',
|
|
||||||
'processed',
|
'processed',
|
||||||
|
'next_run_at',
|
||||||
|
'matching',
|
||||||
]
|
]
|
||||||
|
|
|
@ -507,7 +507,7 @@ retrns
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# execute ticket events
|
# execute ticket notification events
|
||||||
Observer::Ticket::Notification.transaction
|
Observer::Ticket::Notification.transaction
|
||||||
|
|
||||||
# run postmaster post filter
|
# run postmaster post filter
|
||||||
|
|
|
@ -6,8 +6,8 @@ class Job < ApplicationModel
|
||||||
store :perform
|
store :perform
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
before_create :updated_matching
|
before_create :updated_matching, :update_next_run_at
|
||||||
before_update :updated_matching
|
before_update :updated_matching, :update_next_run_at
|
||||||
|
|
||||||
notify_clients_support
|
notify_clients_support
|
||||||
|
|
||||||
|
@ -37,6 +37,11 @@ class Job < ApplicationModel
|
||||||
|
|
||||||
if tickets
|
if tickets
|
||||||
tickets.each do |ticket|
|
tickets.each do |ticket|
|
||||||
|
|
||||||
|
# use transaction
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
UserInfo.current_user_id = 1
|
||||||
|
|
||||||
logger.debug "Perform job #{job.perform.inspect} in Ticket.find(#{ticket.id})"
|
logger.debug "Perform job #{job.perform.inspect} in Ticket.find(#{ticket.id})"
|
||||||
changed = false
|
changed = false
|
||||||
job.perform.each do |key, value|
|
job.perform.each do |key, value|
|
||||||
|
@ -50,8 +55,13 @@ class Job < ApplicationModel
|
||||||
logger.debug "set #{object_name}.#{attribute} = #{value['value'].inspect}"
|
logger.debug "set #{object_name}.#{attribute} = #{value['value'].inspect}"
|
||||||
end
|
end
|
||||||
next if !changed
|
next if !changed
|
||||||
ticket.updated_by_id = 1
|
|
||||||
ticket.save
|
ticket.save
|
||||||
|
|
||||||
|
# execute ticket notification events
|
||||||
|
if !job.disable_notification
|
||||||
|
Observer::Ticket::Notification.transaction
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,6 +73,7 @@ class Job < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def executable?
|
def executable?
|
||||||
|
return false if !active
|
||||||
|
|
||||||
# only execute jobs, older then 1 min, to give admin posibility to change
|
# only execute jobs, older then 1 min, to give admin posibility to change
|
||||||
return false if updated_at > Time.zone.now - 1.minute
|
return false if updated_at > Time.zone.now - 1.minute
|
||||||
|
@ -74,8 +85,7 @@ class Job < ApplicationModel
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def in_timeplan?
|
def in_timeplan?(time = Time.zone.now)
|
||||||
time = Time.zone.now
|
|
||||||
day_map = {
|
day_map = {
|
||||||
0 => 'Sun',
|
0 => 'Sun',
|
||||||
1 => 'Mon',
|
1 => 'Mon',
|
||||||
|
@ -106,12 +116,117 @@ class Job < ApplicationModel
|
||||||
ticket_count || 0
|
ticket_count || 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def next_run_at_calculate(time = Time.zone.now)
|
||||||
|
if last_run_at
|
||||||
|
diff = time - last_run_at
|
||||||
|
if diff > 0
|
||||||
|
time = time + 10.minutes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
day_map = {
|
||||||
|
0 => 'Sun',
|
||||||
|
1 => 'Mon',
|
||||||
|
2 => 'Tue',
|
||||||
|
3 => 'Wed',
|
||||||
|
4 => 'Thu',
|
||||||
|
5 => 'Fri',
|
||||||
|
6 => 'Sat',
|
||||||
|
}
|
||||||
|
return nil if !active
|
||||||
|
return nil if !timeplan['days']
|
||||||
|
return nil if !timeplan['hours']
|
||||||
|
return nil if !timeplan['minutes']
|
||||||
|
|
||||||
|
# loop week days
|
||||||
|
(0..7).each do |day_counter|
|
||||||
|
time_to_check = nil
|
||||||
|
day_to_check = if day_counter == 0
|
||||||
|
time
|
||||||
|
else
|
||||||
|
time + 1.day
|
||||||
|
end
|
||||||
|
if !timeplan['days'][day_map[day_to_check.wday]]
|
||||||
|
|
||||||
|
# start on next day at 00:00:00
|
||||||
|
time = day_to_check - day_to_check.sec.seconds
|
||||||
|
time = time - day_to_check.min.minutes
|
||||||
|
time = time - day_to_check.hour.hours
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
min = day_to_check.min
|
||||||
|
if min < 9
|
||||||
|
min = 0
|
||||||
|
elsif min < 20
|
||||||
|
min = 10
|
||||||
|
elsif min < 30
|
||||||
|
min = 20
|
||||||
|
elsif min < 40
|
||||||
|
min = 30
|
||||||
|
elsif min < 50
|
||||||
|
min = 40
|
||||||
|
elsif min < 60
|
||||||
|
min = 50
|
||||||
|
end
|
||||||
|
|
||||||
|
# move to [0-5]0:00 time stamps
|
||||||
|
day_to_check = day_to_check - day_to_check.min.minutes + min.minutes
|
||||||
|
day_to_check = day_to_check - day_to_check.sec.seconds
|
||||||
|
|
||||||
|
# loop minutes till next full hour
|
||||||
|
if day_to_check.min != 0
|
||||||
|
(0..5).each do |minute_counter|
|
||||||
|
if minute_counter != 0
|
||||||
|
break if day_to_check.min == 0
|
||||||
|
day_to_check = day_to_check + 10.minutes
|
||||||
|
end
|
||||||
|
next if !timeplan['hours'][day_to_check.hour] && !timeplan['hours'][day_to_check.hour.to_s]
|
||||||
|
next if !timeplan['minutes'][match_minutes(day_to_check.min)] && !timeplan['minutes'][match_minutes(day_to_check.min).to_s]
|
||||||
|
return day_to_check
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# loop hours
|
||||||
|
hour_to_check = nil
|
||||||
|
(0..23).each do |hour_counter|
|
||||||
|
hour_to_check = day_to_check + hour_counter.hours
|
||||||
|
|
||||||
|
# start on next day
|
||||||
|
if hour_to_check.day != day_to_check.day
|
||||||
|
time = day_to_check - day_to_check.hour.hours
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
# ignore not configured hours
|
||||||
|
next if !timeplan['hours'][hour_to_check.hour] && !timeplan['hours'][hour_to_check.hour.to_s]
|
||||||
|
return nil if !hour_to_check
|
||||||
|
|
||||||
|
# loop minutes
|
||||||
|
minute_to_check = nil
|
||||||
|
(0..5).each do |minute_counter|
|
||||||
|
minute_to_check = hour_to_check + minute_counter.minutes * 10
|
||||||
|
next if !timeplan['minutes'][match_minutes(minute_to_check.min)] && !timeplan['minutes'][match_minutes(minute_to_check.min).to_s]
|
||||||
|
time_to_check = minute_to_check
|
||||||
|
break
|
||||||
|
end
|
||||||
|
next if !minute_to_check
|
||||||
|
return time_to_check
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def updated_matching
|
def updated_matching
|
||||||
self.matching = matching_count
|
self.matching = matching_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_next_run_at
|
||||||
|
self.next_run_at = next_run_at_calculate
|
||||||
|
end
|
||||||
|
|
||||||
def match_minutes(minutes)
|
def match_minutes(minutes)
|
||||||
return 0 if minutes < 10
|
return 0 if minutes < 10
|
||||||
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i
|
"#{minutes.to_s.gsub(/(\d)\d/, '\\1')}0".to_i
|
||||||
|
|
|
@ -238,6 +238,7 @@ class CreateTicket < ActiveRecord::Migration
|
||||||
t.column :perform, :string, limit: 2500, null: false
|
t.column :perform, :string, limit: 2500, null: false
|
||||||
t.column :disable_notification, :boolean, null: false, default: true
|
t.column :disable_notification, :boolean, null: false, default: true
|
||||||
t.column :last_run_at, :timestamp, null: true
|
t.column :last_run_at, :timestamp, null: true
|
||||||
|
t.column :next_run_at, :timestamp, null: true
|
||||||
t.column :running, :boolean, null: false, default: false
|
t.column :running, :boolean, null: false, default: false
|
||||||
t.column :processed, :integer, null: false, default: 0
|
t.column :processed, :integer, null: false, default: 0
|
||||||
t.column :matching, :integer, null: false
|
t.column :matching, :integer, null: false
|
||||||
|
|
|
@ -22,6 +22,7 @@ class RenewTriggers < ActiveRecord::Migration
|
||||||
t.column :perform, :string, limit: 2500, null: false
|
t.column :perform, :string, limit: 2500, null: false
|
||||||
t.column :disable_notification, :boolean, null: false, default: true
|
t.column :disable_notification, :boolean, null: false, default: true
|
||||||
t.column :last_run_at, :timestamp, null: true
|
t.column :last_run_at, :timestamp, null: true
|
||||||
|
t.column :next_run_at, :timestamp, null: true
|
||||||
t.column :running, :boolean, null: false, default: false
|
t.column :running, :boolean, null: false, default: false
|
||||||
t.column :processed, :integer, null: false, default: 0
|
t.column :processed, :integer, null: false, default: 0
|
||||||
t.column :matching, :integer, null: false, default: 0
|
t.column :matching, :integer, null: false, default: 0
|
|
@ -130,6 +130,7 @@ class JobTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
updated_at: Time.zone.now,
|
updated_at: Time.zone.now,
|
||||||
)
|
)
|
||||||
|
assert_not(job1.next_run_at)
|
||||||
assert_not(job1.executable?)
|
assert_not(job1.executable?)
|
||||||
|
|
||||||
job1.last_run_at = Time.zone.now - 15.minutes
|
job1.last_run_at = Time.zone.now - 15.minutes
|
||||||
|
@ -140,6 +141,14 @@ class JobTest < ActiveSupport::TestCase
|
||||||
job1.save
|
job1.save
|
||||||
assert(job1.executable?)
|
assert(job1.executable?)
|
||||||
|
|
||||||
|
job1.active = false
|
||||||
|
job1.save
|
||||||
|
assert_not(job1.executable?)
|
||||||
|
|
||||||
|
job1.active = true
|
||||||
|
job1.save
|
||||||
|
assert_not(job1.executable?)
|
||||||
|
|
||||||
assert_not(job1.in_timeplan?)
|
assert_not(job1.in_timeplan?)
|
||||||
time = Time.zone.now
|
time = Time.zone.now
|
||||||
day_map = {
|
day_map = {
|
||||||
|
@ -168,7 +177,7 @@ class JobTest < ActiveSupport::TestCase
|
||||||
min = 30
|
min = 30
|
||||||
elsif min < 50
|
elsif min < 50
|
||||||
min = 40
|
min = 40
|
||||||
elsif min < 59
|
elsif min < 60
|
||||||
min = 50
|
min = 50
|
||||||
end
|
end
|
||||||
job1.timeplan['minutes'][min.to_s] = true
|
job1.timeplan['minutes'][min.to_s] = true
|
||||||
|
@ -187,6 +196,7 @@ class JobTest < ActiveSupport::TestCase
|
||||||
job1.save
|
job1.save
|
||||||
Job.run
|
Job.run
|
||||||
|
|
||||||
|
assert(job1.next_run_at)
|
||||||
assert(job1.executable?)
|
assert(job1.executable?)
|
||||||
assert(job1.in_timeplan?)
|
assert(job1.in_timeplan?)
|
||||||
|
|
||||||
|
@ -422,4 +432,294 @@ class JobTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'case 3' do
|
||||||
|
|
||||||
|
# create jobs
|
||||||
|
job1 = Job.create_or_update(
|
||||||
|
name: 'Test Job1',
|
||||||
|
timeplan: {
|
||||||
|
days: {
|
||||||
|
Mon: true,
|
||||||
|
Tue: false,
|
||||||
|
Wed: false,
|
||||||
|
Thu: false,
|
||||||
|
Fri: true,
|
||||||
|
Sat: false,
|
||||||
|
Sun: false,
|
||||||
|
},
|
||||||
|
hours: {
|
||||||
|
0 => false,
|
||||||
|
1 => true,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
5 => false,
|
||||||
|
6 => false,
|
||||||
|
7 => false,
|
||||||
|
8 => false,
|
||||||
|
9 => false,
|
||||||
|
10 => true,
|
||||||
|
11 => false,
|
||||||
|
12 => false,
|
||||||
|
13 => false,
|
||||||
|
14 => false,
|
||||||
|
15 => false,
|
||||||
|
16 => false,
|
||||||
|
17 => false,
|
||||||
|
18 => false,
|
||||||
|
19 => false,
|
||||||
|
20 => false,
|
||||||
|
21 => false,
|
||||||
|
22 => false,
|
||||||
|
23 => false,
|
||||||
|
},
|
||||||
|
minutes: {
|
||||||
|
0 => true,
|
||||||
|
10 => false,
|
||||||
|
20 => false,
|
||||||
|
30 => false,
|
||||||
|
40 => true,
|
||||||
|
50 => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => { 'operator' => 'is', 'value' => [Ticket::State.lookup(name: 'new').id.to_s, Ticket::State.lookup(name: 'open').id.to_s] },
|
||||||
|
'ticket.created_at' => { 'operator' => 'before (relative)', 'value' => '2', 'range' => 'day' },
|
||||||
|
},
|
||||||
|
perform: {
|
||||||
|
'ticket.state_id' => { 'value' => Ticket::State.lookup(name: 'closed').id.to_s }
|
||||||
|
},
|
||||||
|
disable_notification: true,
|
||||||
|
last_run_at: nil,
|
||||||
|
active: true,
|
||||||
|
created_by_id: 1,
|
||||||
|
created_at: Time.zone.now,
|
||||||
|
updated_by_id: 1,
|
||||||
|
updated_at: Time.zone.now,
|
||||||
|
)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-18 09:17:13 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 10:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-18 10:37:13 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 10:40:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-17 09:17:13 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-17 11:17:13 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-19 11:17:13 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-21 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-22 00:59:59 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-25 00:59:59 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-24 00:59:59 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-24 23:59:59 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-25 01:00:01 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-25 01:09:01 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:40:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-25 01:09:59 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-25 01:40:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
job1.last_run_at = Time.zone.parse('2016-03-18 10:00:01 UTC')
|
||||||
|
job1.save
|
||||||
|
time_now = Time.zone.parse('2016-03-18 10:00:02 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 10:40:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
job1.last_run_at = Time.zone.parse('2016-03-18 10:40:01 UTC')
|
||||||
|
job1.save
|
||||||
|
time_now = Time.zone.parse('2016-03-18 10:40:02 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-21 01:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'case 4' do
|
||||||
|
|
||||||
|
# create jobs
|
||||||
|
job1 = Job.create_or_update(
|
||||||
|
name: 'Test Job1',
|
||||||
|
timeplan: {
|
||||||
|
days: {
|
||||||
|
Mon: true,
|
||||||
|
Tue: false,
|
||||||
|
Wed: false,
|
||||||
|
Thu: false,
|
||||||
|
Fri: true,
|
||||||
|
Sat: false,
|
||||||
|
Sun: false,
|
||||||
|
},
|
||||||
|
hours: {
|
||||||
|
0 => true,
|
||||||
|
1 => false,
|
||||||
|
2 => false,
|
||||||
|
3 => false,
|
||||||
|
4 => false,
|
||||||
|
5 => false,
|
||||||
|
6 => false,
|
||||||
|
7 => false,
|
||||||
|
8 => false,
|
||||||
|
9 => false,
|
||||||
|
10 => true,
|
||||||
|
11 => false,
|
||||||
|
12 => false,
|
||||||
|
13 => false,
|
||||||
|
14 => false,
|
||||||
|
15 => false,
|
||||||
|
16 => false,
|
||||||
|
17 => false,
|
||||||
|
18 => false,
|
||||||
|
19 => false,
|
||||||
|
20 => false,
|
||||||
|
21 => false,
|
||||||
|
22 => false,
|
||||||
|
23 => false,
|
||||||
|
},
|
||||||
|
minutes: {
|
||||||
|
0 => true,
|
||||||
|
10 => false,
|
||||||
|
20 => false,
|
||||||
|
30 => false,
|
||||||
|
40 => true,
|
||||||
|
50 => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => { 'operator' => 'is', 'value' => [Ticket::State.lookup(name: 'new').id.to_s, Ticket::State.lookup(name: 'open').id.to_s] },
|
||||||
|
'ticket.created_at' => { 'operator' => 'before (relative)', 'value' => '2', 'range' => 'day' },
|
||||||
|
},
|
||||||
|
perform: {
|
||||||
|
'ticket.state_id' => { 'value' => Ticket::State.lookup(name: 'closed').id.to_s }
|
||||||
|
},
|
||||||
|
disable_notification: true,
|
||||||
|
last_run_at: nil,
|
||||||
|
active: true,
|
||||||
|
created_by_id: 1,
|
||||||
|
created_at: Time.zone.now,
|
||||||
|
updated_by_id: 1,
|
||||||
|
updated_at: Time.zone.now,
|
||||||
|
)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-17 23:51:23 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 00:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
job1.last_run_at = Time.zone.parse('2016-03-17 23:45:01 UTC')
|
||||||
|
job1.save
|
||||||
|
time_now = Time.zone.parse('2016-03-17 23:51:23 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 00:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
job1.last_run_at = Time.zone.parse('2016-03-17 23:59:01 UTC')
|
||||||
|
job1.save
|
||||||
|
time_now = Time.zone.parse('2016-03-17 23:59:23 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-18 00:40:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-17 23:59:23 UTC')
|
||||||
|
assert_not(job1.in_timeplan?(time_now))
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-18 00:01:23 UTC')
|
||||||
|
assert(job1.in_timeplan?(time_now))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'case 5' do
|
||||||
|
|
||||||
|
# create jobs
|
||||||
|
job1 = Job.create_or_update(
|
||||||
|
name: 'Test Job1',
|
||||||
|
timeplan: {
|
||||||
|
days: {
|
||||||
|
Mon: true,
|
||||||
|
Tue: false,
|
||||||
|
Wed: false,
|
||||||
|
Thu: false,
|
||||||
|
Fri: false,
|
||||||
|
Sat: false,
|
||||||
|
Sun: false,
|
||||||
|
},
|
||||||
|
hours: {
|
||||||
|
'0' => true,
|
||||||
|
'1' => false,
|
||||||
|
'2' => false,
|
||||||
|
'3' => false,
|
||||||
|
'4' => false,
|
||||||
|
'5' => false,
|
||||||
|
'6' => false,
|
||||||
|
'7' => false,
|
||||||
|
'8' => false,
|
||||||
|
'9' => false,
|
||||||
|
'10' => false,
|
||||||
|
'11' => false,
|
||||||
|
'12' => false,
|
||||||
|
'13' => false,
|
||||||
|
'14' => false,
|
||||||
|
'15' => false,
|
||||||
|
'16' => false,
|
||||||
|
'17' => false,
|
||||||
|
'18' => false,
|
||||||
|
'19' => false,
|
||||||
|
'20' => false,
|
||||||
|
'21' => false,
|
||||||
|
'22' => false,
|
||||||
|
'23' => false,
|
||||||
|
},
|
||||||
|
minutes: {
|
||||||
|
'0' => true,
|
||||||
|
'10' => false,
|
||||||
|
'20' => false,
|
||||||
|
'30' => false,
|
||||||
|
'40' => false,
|
||||||
|
'50' => false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
'ticket.state_id' => { 'operator' => 'is', 'value' => [Ticket::State.lookup(name: 'new').id.to_s, Ticket::State.lookup(name: 'open').id.to_s] },
|
||||||
|
'ticket.created_at' => { 'operator' => 'before (relative)', 'value' => '2', 'range' => 'day' },
|
||||||
|
},
|
||||||
|
perform: {
|
||||||
|
'ticket.state_id' => { 'value' => Ticket::State.lookup(name: 'closed').id.to_s }
|
||||||
|
},
|
||||||
|
disable_notification: true,
|
||||||
|
last_run_at: nil,
|
||||||
|
active: true,
|
||||||
|
created_by_id: 1,
|
||||||
|
created_at: Time.zone.now,
|
||||||
|
updated_by_id: 1,
|
||||||
|
updated_at: Time.zone.now,
|
||||||
|
)
|
||||||
|
|
||||||
|
time_now = Time.zone.parse('2016-03-17 23:51:23 UTC')
|
||||||
|
next_run_at = job1.next_run_at_calculate(time_now)
|
||||||
|
assert_equal('2016-03-21 00:00:00 UTC', next_run_at.to_s)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue