Init version of scheduler.

This commit is contained in:
Martin Edenhofer 2014-12-26 00:41:00 +01:00
parent 32d404def9
commit 51d485670e
15 changed files with 687 additions and 159 deletions

View file

@ -923,18 +923,286 @@ class App.ControllerForm extends App.Controller
item.find( "[name=\"#{attribute.name}::count\"]").find("option[value=\"#{attribute.value.count}\"]").attr( 'selected', 'selected' ) item.find( "[name=\"#{attribute.name}::count\"]").find("option[value=\"#{attribute.value.count}\"]").attr( 'selected', 'selected' )
item.find( "[name=\"#{attribute.name}::area\"]").find("option[value=\"#{attribute.value.area}\"]").attr( 'selected', 'selected' ) item.find( "[name=\"#{attribute.name}::area\"]").find("option[value=\"#{attribute.value.area}\"]").attr( 'selected', 'selected' )
# ticket attribute selection # ticket attribute set
else if attribute.tag is 'ticket_attribute_selection' else if attribute.tag is 'ticket_attribute_set'
# list of possible attributes # list of possible attributes
item = $( item = $(
App.view('generic/ticket_attribute_selection')( App.view('generic/ticket_attribute_manage')(
attribute: attribute
)
)
addShownAttribute = ( key, value ) =>
parts = key.split(/::/)
key = parts[0]
type = parts[1]
if key is 'tickets.title'
attribute_config = {
name: attribute.name + '::tickets.title'
display: 'Title'
tag: 'input'
type: 'text'
null: false
value: value
remove: true
}
else if key is 'tickets.group_id'
attribute_config = {
name: attribute.name + '::tickets.group_id'
display: 'Group'
tag: 'select'
multiple: false
null: false
nulloption: false
relation: 'Group'
value: value
remove: true
}
else if key is 'tickets.owner_id' || key is 'tickets.customer_id'
display = 'Owner'
name = 'owner_id'
if key is 'customer_id'
display = 'Customer'
name = 'customer_id'
attribute_config = {
name: attribute.name + '::tickets.' + name
display: display
tag: 'select'
multiple: false
null: false
nulloption: false
relation: 'User'
value: value || null
remove: true
filter: ( all, type ) ->
return all if type isnt 'collection'
all = _.filter( all, (item) ->
return if item.id is 1
return item
)
all.unshift( {
id: ''
name: '--'
} )
all.unshift( {
id: 1
name: '*** not set ***'
} )
all.unshift( {
id: 'current_user.id'
name: '*** current user ***'
} )
all
}
else if key is 'tickets.organization_id'
attribute_config = {
name: attribute.name + '::tickets.organization_id'
display: 'Organization'
tag: 'select'
multiple: false
null: false
nulloption: false
relation: 'Organization'
value: value || null
remove: true
filter: ( all, type ) ->
return all if type isnt 'collection'
all.unshift( {
id: ''
name: '--'
} )
all.unshift( {
id: 'current_user.organization_id'
name: '*** organization of current user ***'
} )
all
}
else if key is 'tickets.state_id'
attribute_config = {
name: attribute.name + '::tickets.state_id'
display: 'State'
tag: 'select'
multiple: false
null: false
nulloption: false
relation: 'TicketState'
value: value
translate: true
remove: true
}
else if key is 'tickets.priority_id'
attribute_config = {
name: attribute.name + '::tickets.priority_id'
display: 'Priority'
tag: 'select'
multiple: false
null: false
nulloption: false
relation: 'TicketPriority'
value: value
translate: true
remove: true
}
else
attribute_config = {
name: attribute.name + '::' + key
display: 'FIXME!'
tag: 'input'
type: 'text'
value: value
remove: true
}
item.find('select[name=ticket_attribute_list] option[value="' + key + '"]').hide().prop('disabled', true)
itemSub = @formGenItem( attribute_config )
itemSub.find('.glyphicon-minus').bind('click', (e) ->
e.preventDefault()
value = $(e.target).closest('.controls').find('[name]').attr('name')
if value
value = value.replace("#{attribute.name}::", '')
$(e.target).closest('.sub_attribute').find('select[name=ticket_attribute_list] option[value="' + value + '"]').show().prop('disabled', false)
$(@).parent().parent().parent().remove()
)
# itemSub.append('<a href=\"#\" class=\"icon-minus\"></a>')
item.find('.ticket_attribute_item').append( itemSub )
# list of existing attributes
attribute_config = {
name: 'ticket_attribute_list'
display: 'Add Attribute'
tag: 'select'
multiple: false
null: false
# nulloption: true
options: [
{
value: ''
name: '-- Ticket --'
selected: false
disable: true
},
{
value: 'tickets.title'
name: 'Title'
selected: false
disable: false
},
{
value: 'tickets.group_id'
name: 'Group'
selected: false
disable: false
},
{
value: 'tickets.state_id'
name: 'State'
selected: false
disable: false
},
{
value: 'tickets.priority_id'
name: 'Priority'
selected: true
disable: false
},
{
value: 'tickets.owner_id'
name: 'Owner'
selected: true
disable: false
},
# # {
# value: 'tag'
# name: 'Tag'
# selected: true
# disable: false
# },
# {
# value: '-a'
# name: '-- ' + App.i18n.translateInline('Article') + ' --'
# selected: false
# disable: true
# },
# {
# value: 'ticket_articles.from'
# name: 'From'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.to'
# name: 'To'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.cc'
# name: 'Cc'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.subject'
# name: 'Subject'
# selected: true
# disable: false
# },
# {
# value: 'ticket_articles.body'
# name: 'Text'
# selected: true
# disable: false
# },
{
value: '-c'
name: '-- ' + App.i18n.translateInline('Customer') + ' --'
selected: false
disable: true
},
{
value: 'customers.id'
name: 'Customer'
selected: true
disable: false
},
{
value: 'organization.id'
name: 'Organization'
selected: true
disable: false
},
]
default: ''
translate: true
class: 'medium'
add: true
}
list = @formGenItem( attribute_config )
list.find('.glyphicon-plus').bind('click', (e) ->
e.preventDefault()
value = $(e.target).closest('.controls').find('[name=ticket_attribute_list]').val()
addShownAttribute( value, '' )
)
item.find('.ticket_attribute_list').prepend( list )
# list of shown attributes
show = []
if attribute.value
for key, value of attribute.value
addShownAttribute( key, value )
# ticket attribute selection
else if attribute.tag is 'ticket_attribute_selection'
# list of possible attributes
item = $(
App.view('generic/ticket_attribute_manage')(
attribute: attribute attribute: attribute
) )
) )
addShownAttribute = ( key, value ) => addShownAttribute = ( key, value ) =>
console.log( 'addShownAttribute', key, value )
parts = key.split(/::/) parts = key.split(/::/)
key = parts[0] key = parts[0]
type = parts[1] type = parts[1]
@ -946,7 +1214,6 @@ class App.ControllerForm extends App.Controller
type: 'text' type: 'text'
null: false null: false
value: value value: value
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.title' else if key is 'tickets.title'
@ -957,7 +1224,6 @@ class App.ControllerForm extends App.Controller
type: 'text' type: 'text'
null: false null: false
value: value value: value
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.group_id' else if key is 'tickets.group_id'
@ -970,7 +1236,6 @@ class App.ControllerForm extends App.Controller
nulloption: false nulloption: false
relation: 'Group' relation: 'Group'
value: value value: value
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.owner_id' || key is 'tickets.customer_id' else if key is 'tickets.owner_id' || key is 'tickets.customer_id'
@ -988,7 +1253,6 @@ class App.ControllerForm extends App.Controller
nulloption: false nulloption: false
relation: 'User' relation: 'User'
value: value || null value: value || null
class: 'medium'
remove: true remove: true
filter: ( all, type ) -> filter: ( all, type ) ->
return all if type isnt 'collection' return all if type isnt 'collection'
@ -1020,7 +1284,6 @@ class App.ControllerForm extends App.Controller
nulloption: false nulloption: false
relation: 'Organization' relation: 'Organization'
value: value || null value: value || null
class: 'medium'
remove: true remove: true
filter: ( all, type ) -> filter: ( all, type ) ->
return all if type isnt 'collection' return all if type isnt 'collection'
@ -1045,7 +1308,6 @@ class App.ControllerForm extends App.Controller
relation: 'TicketState' relation: 'TicketState'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.priority_id' else if key is 'tickets.priority_id'
@ -1059,7 +1321,6 @@ class App.ControllerForm extends App.Controller
relation: 'TicketPriority' relation: 'TicketPriority'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.created_at' && ( type is '<>' || value.count ) else if key is 'tickets.created_at' && ( type is '<>' || value.count )
@ -1069,7 +1330,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_before_last' tag: 'time_before_last'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.created_at' && ( type is '><' || 0 ) else if key is 'tickets.created_at' && ( type is '><' || 0 )
@ -1079,7 +1339,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_range' tag: 'time_range'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.close_time' && ( type is '<>' || value.count ) else if key is 'tickets.close_time' && ( type is '<>' || value.count )
@ -1089,7 +1348,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_before_last' tag: 'time_before_last'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.close_time' && ( type is '><' || 0 ) else if key is 'tickets.close_time' && ( type is '><' || 0 )
@ -1099,7 +1357,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_range' tag: 'time_range'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.updated_at' && ( type is '<>' || value.count ) else if key is 'tickets.updated_at' && ( type is '<>' || value.count )
@ -1109,7 +1366,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_before_last' tag: 'time_before_last'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.updated_at' && ( type is '><' || 0 ) else if key is 'tickets.updated_at' && ( type is '><' || 0 )
@ -1119,7 +1375,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_range' tag: 'time_range'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.escalation_time' && ( type is '<>' || value.count ) else if key is 'tickets.escalation_time' && ( type is '<>' || value.count )
@ -1129,7 +1384,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_before_last' tag: 'time_before_last'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else if key is 'tickets.escalation_time' && ( type is '><' || 0 ) else if key is 'tickets.escalation_time' && ( type is '><' || 0 )
@ -1139,7 +1393,6 @@ class App.ControllerForm extends App.Controller
tag: 'time_range' tag: 'time_range'
value: value value: value
translate: true translate: true
class: 'medium'
remove: true remove: true
} }
else else
@ -1149,24 +1402,23 @@ class App.ControllerForm extends App.Controller
tag: 'input' tag: 'input'
type: 'text' type: 'text'
value: value value: value
class: 'medium'
remove: true remove: true
} }
item.find('select[name=ticket_attribute_list] option[value="' + key + '"]').hide().prop('disabled', true)
itemSub = @formGenItem( attribute_config ) itemSub = @formGenItem( attribute_config )
itemSub.find('.glyphicon-minus').bind('click', (e) -> itemSub.find('.glyphicon-minus').bind('click', (e) ->
e.preventDefault() e.preventDefault()
value = $(e.target).closest('.controls').find('[name]').attr('name')
if value
value = value.replace("#{attribute.name}::", '')
$(e.target).closest('.sub_attribute').find('select[name=ticket_attribute_list] option[value="' + value + '"]').show().prop('disabled', false)
$(@).parent().parent().parent().remove() $(@).parent().parent().parent().remove()
) )
# itemSub.append('<a href=\"#\" class=\"icon-minus\"></a>') # itemSub.append('<a href=\"#\" class=\"icon-minus\"></a>')
item.find('.ticket_attribute_item').append( itemSub ) item.find('.ticket_attribute_item').append( itemSub )
# list of shown attributes
show = []
if attribute.value
for key, value of attribute.value
addShownAttribute( key, value )
# list of existing attributes # list of existing attributes
attribute_config = { attribute_config = {
name: 'ticket_attribute_list' name: 'ticket_attribute_list'
@ -1182,19 +1434,18 @@ class App.ControllerForm extends App.Controller
selected: false selected: false
disable: true disable: true
}, },
# {
#{ value: 'tickets.number'
# value: 'tickets.number' name: 'Number'
# name: 'Number' selected: false
# selected: true disable: false
# disable: false },
#}, {
#{ value: 'tickets.title'
# value: 'tickets.title' name: 'Title'
# name: 'Title' selected: false
# selected: true disable: false
# disable: false },
#},
{ {
value: 'tickets.group_id' value: 'tickets.group_id'
name: 'Group' name: 'Group'
@ -1373,12 +1624,100 @@ class App.ControllerForm extends App.Controller
list.find('.glyphicon-plus').bind('click', (e) -> list.find('.glyphicon-plus').bind('click', (e) ->
e.preventDefault() e.preventDefault()
value = $(e.target).closest('.controls').find('[name=ticket_attribute_list]').val()
value = $(e.target).parents().find('[name=ticket_attribute_list]').val()
addShownAttribute( value, '' ) addShownAttribute( value, '' )
) )
item.find('.ticket_attribute_list').prepend( list ) item.find('.ticket_attribute_list').prepend( list )
# list of shown attributes
show = []
if attribute.value
for key, value of attribute.value
addShownAttribute( key, value )
# timeplan
else if attribute.tag is 'timeplan'
item = $( App.view('generic/timeplan')( attribute: attribute ) )
attribute_config = {
name: "#{attribute.name}::days"
tag: 'select'
multiple: true
null: false
options: [
{
value: 'mon'
name: 'Monday'
selected: false
disable: false
},
{
value: 'tue'
name: 'Tuesday'
selected: false
disable: false
},
{
value: 'wed'
name: 'Wednesday'
selected: false
disable: false
},
{
value: 'thu'
name: 'Thursday'
selected: false
disable: false
},
{
value: 'fri'
name: 'Friday'
selected: false
disable: false
},
{
value: 'sat'
name: 'Saturday'
selected: false
disable: false
},
{
value: 'sun'
name: 'Sunday'
selected: false
disable: false
},
]
default: attribute.default?.days
}
item.find('.days').append( @formGenItem( attribute_config ) )
hours = {}
for hour in [0..23]
localHour = "0#{hour}"
hours[hour] = localHour.substr(localHour.length-2,2)
attribute_config = {
name: "#{attribute.name}::hours"
tag: 'select'
multiple: true
null: false
options: hours
default: attribute.default?.hours
}
item.find('.hours').append( @formGenItem( attribute_config ) )
minutes = {}
for minute in [0..5]
minutes["#{minute}0"] = "#{minute}0"
attribute_config = {
name: "#{attribute.name}::minutes"
tag: 'select'
multiple: true
null: false
options: minutes
default: attribute.default?.miuntes
}
item.find('.minutes').append( @formGenItem( attribute_config ) )
# input # input
else else
item = $( App.view('generic/input')( attribute: attribute ) ) item = $( App.view('generic/input')( attribute: attribute ) )

View file

@ -5,17 +5,23 @@ class Index extends App.ControllerContent
# check authentication # check authentication
return if !@authenticate() return if !@authenticate()
# set title new App.ControllerGenericIndex(
@title 'Scheduler' el: @el,
@navupdate '#scheduler' id: @id,
genericObject: 'Job',
# render page pageData: {
@render() title: 'Schedulers',
home: 'schedulers',
render: -> object: 'Scheduler',
objects: 'Schedulers',
@html App.view('scheduler')( navupdate: '#schedulers',
head: 'some header' notes: [
'Scheduler are ...'
],
buttons: [
{ name: 'New Scheduler', 'data-type': 'new', class: 'btn--success' },
],
},
) )
App.Config.set( 'Scheduler', { prio: 2000, name: 'Schedulers', parent: '#manage', target: '#manage/schedulers', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) App.Config.set( 'Scheduler', { prio: 3000, name: 'Schedulers', parent: '#manage', target: '#manage/schedulers', controller: Index, role: ['Admin'] }, 'NavBarAdmin' )

View file

@ -18,8 +18,4 @@ class Index extends App.ControllerContent
head: 'some header' head: 'some header'
) )
#App.Config.set( 'trigger', Index, 'Routes' ) App.Config.set( 'Trigger', { prio: 3100, name: 'Triggers', parent: '#manage', target: '#manage/triggers', controller: Index, role: ['Admin'] }, 'NavBarAdmin' )
#App.Config.set( 'Trigger', { prio: 3000, parent: '#admin', name: 'Trigger', target: '#trigger', role: ['Admin'] }, 'NavBar' )
App.Config.set( 'Trigger', { prio: 3000, name: 'Triggers', target: '#manage/triggers', controller: Index, role: ['Admin'] }, 'NavBarLevel2' )

View file

@ -0,0 +1,27 @@
class App.Job extends App.Model
@configure 'Job', 'name', 'timeplan', 'condition', 'execute', 'note', 'active'
@extend Spine.Model.Ajax
@url: @apiPath + '/jobs'
@configure_attributes = [
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
{ name: 'timeplan', display: 'The times where the job should run.', tag: 'timeplan', null: true },
{ name: 'condition', display: 'Conditions for matching objects.', tag: 'ticket_attribute_selection', null: true },
{ name: 'execute', display: 'Execute changes on objects.', tag: 'ticket_attribute_set', 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: 'boolean', note: 'boolean', 'default': true, null: false },
{ name: 'matching', display: 'Matching', readonly: 1 },
{ name: 'processed', display: 'Processed', readonly: 1 },
{ name: 'last_run_at', display: 'Last run', type: 'time', 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', type: 'time', readonly: 1 },
{ name: 'updated_by_id', display: 'Updated by', relation: 'User', readonly: 1 },
{ name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 },
]
@configure_delete = true
@configure_overview = [
'name',
'last_run_at',
'matching',
'processed',
]

View file

@ -3,4 +3,3 @@
<hr> <hr>
<div class="ticket_attribute_list"></div> <div class="ticket_attribute_list"></div>
</div> </div>

View file

@ -0,0 +1,11 @@
<div>
<label><%- @T('Days') %>
<div class="days"></div>
</label>
<label><%- @T('Hours') %>
<div class="hours"></div>
</label>
<label><%- @T('Minutes') %>
<div class="minutes"></div>
</label>
</div>

View file

@ -1,91 +0,0 @@
<div class="page-header-title">
<h1>Scheduler <small>Management</small></h1>
</div>
<ul class="nav nav-tabs nav-stacked">
<li><a href="#">Jobs</a></li>
</ul>
<div class="table-overview">
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active"><a href="#channel-inbound" data-toggle="tab">Times</a></li>
<li><a href="#channel-outbound" data-toggle="tab">Properties</a></li>
<li><a href="#channel-filter" data-toggle="tab">Message</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="channel-inbound">
<table class="table table-striped">
<tr>
<th>Host</th>
<th>User</th>
<th>Type</th>
<th>Active</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>wpt234rwr</td>
<td>IMAP</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>l31alal.example.com</td>
<td>wpt23dd4rwr</td>
<td>POP3</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>
<div class="tab-pane" id="channel-outbound">
<table class="table table-striped">
<tr>
<th>Host</th>
<th>User</th>
<th>Type</th>
<th>Active</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>wpt234rwr</td>
<td>SMTP</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>l31alal.example.com</td>
<td>wpt23dd4rwr</td>
<td>Sendmail</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>
<div class="tab-pane" id="channel-filter">
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Active</th>
<th>Last Run</th>
<th>Delete</th>
</tr>
<tr>
<td>lalal.example.com</td>
<td>true</td>
<td>true</td>
<td>x</td>
</tr>
<tr>
<td>wpt23dd4rwr</td>
<td>true</td>
<td>true</td>
<td>x</td>
</tr>
</table>
</div>
</div>
</div>
</div>

View file

@ -23,6 +23,13 @@ class TestsController < ApplicationController
end end
end end
# GET /tests/from_extended
def form
respond_to do |format|
format.html # index.html.erb
end
end
# GET /tests/table # GET /tests/table
def table def table
respond_to do |format| respond_to do |format|

88
app/models/job.rb Normal file
View file

@ -0,0 +1,88 @@
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
class Job < ApplicationModel
store :timeplan
store :condition
store :execute
validates :name, :presence => true
before_create :updated_matching
before_update :updated_matching
after_create :notify_clients_after_create
after_update :notify_clients_after_update
after_destroy :notify_clients_after_destroy
def self.run
time = Time.new
day_map = {
0 => 'sun',
1 => 'mon',
2 => 'tue',
3 => 'wed',
4 => 'thu',
5 => 'fri',
6 => 'sat',
}
jobs = Job.where( :active => true )
jobs.each do |job|
# only execute jobs, older then 2 min, to give admin posibility to change
next if job.updated_at > Time.now - 2.minutes
# check if jobs need to be executed
# ignore if job was running within last 10 min.
next if job.last_run_at > Time.now - 10.minutes
# check day
next if !job.timeplan['days'].include?( day_map[time.wday] )
# check hour
next if !job.timeplan['hours'].include?( time.hour.to_s )
# check min
next if !job.timeplan['minutes'].include?( match_minutes(time.min.to_s) )
# find tickets to change
tickets = Ticket.where( job.condition.permit! ).
order( '`tickets`.`created_at` DESC' ).
limit( 1_000 )
job.processed = tickets.count
tickets.each do |ticket|
#puts "CHANGE #{job.execute.inspect}"
changed = false
job.execute.each do |key, value|
changed = true
attribute = key.split('.', 2).last
#puts "-- #{Ticket.columns_hash[ attribute ].type.to_s}"
#value = 4
#if Ticket.columns_hash[ attribute ].type == :integer
# puts "to i #{attribute}/#{value.inspect}/#{value.to_i.inspect}"
# #value = value.to_i
#end
ticket[attribute] = value
#puts "set #{attribute} = #{value.inspect}"
end
next if !changed
ticket.updated_by_id = 1
ticket.save
end
job.last_run_at = Time.now
job.save
end
true
end
private
def updated_matching
count = Ticket.where( self.condition.permit! ).count
self.matching = count
end
def self.match_minutes(minutes)
minutes.gsub!(/(\d)\d/, "\\1")
minutes.to_s + '0'
end
end

11
config/routes/job.rb Normal file
View file

@ -0,0 +1,11 @@
Zammad::Application.routes.draw do
api_path = Rails.configuration.api_path
# jobs
match api_path + '/jobs', :to => 'jobs#index', :via => :get
match api_path + '/jobs/:id', :to => 'jobs#show', :via => :get
match api_path + '/jobs', :to => 'jobs#create', :via => :post
match api_path + '/jobs/:id', :to => 'jobs#update', :via => :put
match api_path + '/jobs/:id', :to => 'jobs#destroy', :via => :delete
end

View file

@ -4,6 +4,7 @@ Zammad::Application.routes.draw do
match '/tests-ui', :to => 'tests#ui', :via => :get match '/tests-ui', :to => 'tests#ui', :via => :get
match '/tests-model', :to => 'tests#model', :via => :get match '/tests-model', :to => 'tests#model', :via => :get
match '/tests-form', :to => 'tests#form', :via => :get match '/tests-form', :to => 'tests#form', :via => :get
match '/tests-form-extended', :to => 'tests#form_extended', :via => :get
match '/tests-table', :to => 'tests#table', :via => :get match '/tests-table', :to => 'tests#table', :via => :get
match '/tests/wait/:sec', :to => 'tests#wait', :via => :get match '/tests/wait/:sec', :to => 'tests#wait', :via => :get

View file

@ -0,0 +1,25 @@
class CreateJob < ActiveRecord::Migration
def up
create_table :jobs do |t|
t.column :name, :string, :limit => 250, :null => false
t.column :timeplan, :string, :limit => 500, :null => false
t.column :condition, :string, :limit => 2500, :null => false
t.column :execute, :string, :limit => 2500, :null => false
t.column :last_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
t.column :pid, :string, :limit => 250, :null => true
t.column :note, :string, :limit => 250, :null => true
t.column :active, :boolean, :null => false, :default => false
t.column :updated_by_id, :integer, :null => false
t.column :created_by_id, :integer, :null => false
t.timestamps
end
add_index :jobs, [:name], :unique => true
end
def down
drop_table :jobs
end
end

View file

@ -0,0 +1,87 @@
// form
test( "form simple checks", function() {
App.TicketPriority.refresh( [
{
id: 1,
name: '1 low',
note: 'some note 1',
active: true,
created_at: '2014-06-10T11:17:34.000Z',
},
{
id: 2,
name: '2 normal',
note: 'some note 2',
active: false,
created_at: '2014-06-10T10:17:34.000Z',
},
{
id: 3,
name: '3 high',
note: 'some note 3',
active: true,
created_at: '2014-06-10T10:17:44.000Z',
},
{
id: 4,
name: '4 very high',
note: 'some note 4',
active: true,
created_at: '2014-06-10T10:17:54.000Z',
},
] )
// timeplan
$('#forms').append('<hr><h1>form time check</h1><form id="form1"></form>')
var el = $('#form1')
var defaults = {
times: {
days: ['mon', 'wed'],
hours: [2],
},
conditions: {
'tickets.title': 'some title',
'tickets.priority_id': [1,2,3],
},
executions: {
'tickets.title': 'some title new',
'tickets.priority_id': 3,
},
}
new App.ControllerForm({
el: el,
model: {
configure_attributes: [
{ name: 'times', display: 'Times', tag: 'timeplan', null: true, default: defaults['times'] },
{ name: 'conditions', display: 'Conditions', tag: 'ticket_attribute_selection', null: true, default: defaults['conditions'] },
{ name: 'executions', display: 'Executions', tag: 'ticket_attribute_set', null: true, default: defaults['executions'] },
]
},
autofocus: true
});
deepEqual( el.find('[name="times::days"]').val(), ['mon', 'wed'], 'check times::days value')
equal( el.find('[name="times::hours"]').val(), 2, 'check times::hours value')
equal( el.find('[name="times::minutes"]').val(), null, 'check times::minutes value')
var params = App.ControllerForm.params( el )
var test_params = {
times: {
days: ['mon', 'wed'],
hours: '2',
},
conditions: {
'tickets.title': 'some title',
'tickets.priority_id': ['1','3'],
},
executions: {
'tickets.title': 'some title new',
'tickets.priority_id': '3',
},
}
deepEqual( params, test_params, 'form param check' );
});

View file

@ -90,6 +90,28 @@ class AAbUnitTest < TestCase
] ]
browser_single_test(tests) browser_single_test(tests)
end end
def test_form_extended
tests = [
{
:name => 'start',
:instance => browser_instance,
:url => browser_url + '/tests-form-extended',
:action => [
{
:execute => 'wait',
:value => 8,
},
{
:execute => 'match',
:css => '.result .failed',
:value => '0',
:match_result => true,
},
],
},
]
browser_single_test(tests)
end
def test_table def test_table
tests = [ tests = [
{ {