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
|
@ -3,26 +3,28 @@ class App.Job extends App.Model
|
|||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/jobs'
|
||||
@configure_attributes = [
|
||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
|
||||
{ name: 'timeplan', display: 'When should the job run?', tag: 'timer', null: true },
|
||||
{ name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: true },
|
||||
{ name: 'perform', display: 'Execute changes on objects', tag: 'ticket_perform_action', null: 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: 'active', display: 'Active', tag: 'active', default: true },
|
||||
{ name: 'matching', display: 'Matching', readonly: 1 },
|
||||
{ name: 'processed', display: 'Processed', readonly: 1 },
|
||||
{ name: 'last_run_at', display: 'Last run', tag: 'datetime', readonly: 1 },
|
||||
{ name: 'running', display: 'Running', tag: 'boolean', readonly: 1 },
|
||||
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
||||
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
||||
{ 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: 'matching', display: 'Will process', readonly: 1 },
|
||||
{ name: 'processed', display: 'Has processed', 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: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
|
||||
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },
|
||||
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
|
||||
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
|
||||
]
|
||||
@configure_delete = true
|
||||
@configure_overview = [
|
||||
'name',
|
||||
'last_run_at',
|
||||
'matching',
|
||||
'processed',
|
||||
'next_run_at',
|
||||
'matching',
|
||||
]
|
||||
|
|
|
@ -507,7 +507,7 @@ retrns
|
|||
end
|
||||
end
|
||||
|
||||
# execute ticket events
|
||||
# execute ticket notification events
|
||||
Observer::Ticket::Notification.transaction
|
||||
|
||||
# run postmaster post filter
|
||||
|
|
|
@ -6,8 +6,8 @@ class Job < ApplicationModel
|
|||
store :perform
|
||||
validates :name, presence: true
|
||||
|
||||
before_create :updated_matching
|
||||
before_update :updated_matching
|
||||
before_create :updated_matching, :update_next_run_at
|
||||
before_update :updated_matching, :update_next_run_at
|
||||
|
||||
notify_clients_support
|
||||
|
||||
|
@ -37,21 +37,31 @@ class Job < ApplicationModel
|
|||
|
||||
if tickets
|
||||
tickets.each do |ticket|
|
||||
logger.debug "Perform job #{job.perform.inspect} in Ticket.find(#{ticket.id})"
|
||||
changed = false
|
||||
job.perform.each do |key, value|
|
||||
(object_name, attribute) = key.split('.', 2)
|
||||
raise "Unable to update object #{object_name}.#{attribute}, only can update tickets!" if object_name != 'ticket'
|
||||
|
||||
next if ticket[attribute].to_s == value['value'].to_s
|
||||
changed = true
|
||||
# use transaction
|
||||
ActiveRecord::Base.transaction do
|
||||
UserInfo.current_user_id = 1
|
||||
|
||||
ticket[attribute] = value['value']
|
||||
logger.debug "set #{object_name}.#{attribute} = #{value['value'].inspect}"
|
||||
logger.debug "Perform job #{job.perform.inspect} in Ticket.find(#{ticket.id})"
|
||||
changed = false
|
||||
job.perform.each do |key, value|
|
||||
(object_name, attribute) = key.split('.', 2)
|
||||
raise "Unable to update object #{object_name}.#{attribute}, only can update tickets!" if object_name != 'ticket'
|
||||
|
||||
next if ticket[attribute].to_s == value['value'].to_s
|
||||
changed = true
|
||||
|
||||
ticket[attribute] = value['value']
|
||||
logger.debug "set #{object_name}.#{attribute} = #{value['value'].inspect}"
|
||||
end
|
||||
next if !changed
|
||||
ticket.save
|
||||
|
||||
# execute ticket notification events
|
||||
if !job.disable_notification
|
||||
Observer::Ticket::Notification.transaction
|
||||
end
|
||||
end
|
||||
next if !changed
|
||||
ticket.updated_by_id = 1
|
||||
ticket.save
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -63,6 +73,7 @@ class Job < ApplicationModel
|
|||
end
|
||||
|
||||
def executable?
|
||||
return false if !active
|
||||
|
||||
# only execute jobs, older then 1 min, to give admin posibility to change
|
||||
return false if updated_at > Time.zone.now - 1.minute
|
||||
|
@ -74,8 +85,7 @@ class Job < ApplicationModel
|
|||
true
|
||||
end
|
||||
|
||||
def in_timeplan?
|
||||
time = Time.zone.now
|
||||
def in_timeplan?(time = Time.zone.now)
|
||||
day_map = {
|
||||
0 => 'Sun',
|
||||
1 => 'Mon',
|
||||
|
@ -106,12 +116,117 @@ class Job < ApplicationModel
|
|||
ticket_count || 0
|
||||
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
|
||||
|
||||
def updated_matching
|
||||
self.matching = matching_count
|
||||
end
|
||||
|
||||
def update_next_run_at
|
||||
self.next_run_at = next_run_at_calculate
|
||||
end
|
||||
|
||||
def match_minutes(minutes)
|
||||
return 0 if minutes < 10
|
||||
"#{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 :disable_notification, :boolean, null: false, default: 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 :processed, :integer, null: false, default: 0
|
||||
t.column :matching, :integer, null: false
|
||||
|
|
|
@ -22,6 +22,7 @@ class RenewTriggers < ActiveRecord::Migration
|
|||
t.column :perform, :string, limit: 2500, null: false
|
||||
t.column :disable_notification, :boolean, null: false, default: 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 :processed, :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_at: Time.zone.now,
|
||||
)
|
||||
assert_not(job1.next_run_at)
|
||||
assert_not(job1.executable?)
|
||||
|
||||
job1.last_run_at = Time.zone.now - 15.minutes
|
||||
|
@ -140,6 +141,14 @@ class JobTest < ActiveSupport::TestCase
|
|||
job1.save
|
||||
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?)
|
||||
time = Time.zone.now
|
||||
day_map = {
|
||||
|
@ -168,7 +177,7 @@ class JobTest < ActiveSupport::TestCase
|
|||
min = 30
|
||||
elsif min < 50
|
||||
min = 40
|
||||
elsif min < 59
|
||||
elsif min < 60
|
||||
min = 50
|
||||
end
|
||||
job1.timeplan['minutes'][min.to_s] = true
|
||||
|
@ -187,6 +196,7 @@ class JobTest < ActiveSupport::TestCase
|
|||
job1.save
|
||||
Job.run
|
||||
|
||||
assert(job1.next_run_at)
|
||||
assert(job1.executable?)
|
||||
assert(job1.in_timeplan?)
|
||||
|
||||
|
@ -422,4 +432,294 @@ class JobTest < ActiveSupport::TestCase
|
|||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue