Fixed issue#677 - admin interface -> time accounting setting will not be saved.
This commit is contained in:
parent
5e60a2d5f0
commit
9577d7aa05
9 changed files with 1116 additions and 4 deletions
|
@ -663,7 +663,10 @@ class App.TicketZoom extends App.Controller
|
|||
ticketParams = @formParam(@$('.edit'))
|
||||
|
||||
# validate ticket
|
||||
ticket = App.Ticket.find(@ticket_id)
|
||||
# we need to use the full ticket because
|
||||
# the time accouting needs all attributes
|
||||
# for condition check
|
||||
ticket = App.Ticket.fullLocal(@ticket_id)
|
||||
|
||||
# reset article - should not be resubmited on next ticket update
|
||||
ticket.article = undefined
|
||||
|
@ -740,9 +743,9 @@ class App.TicketZoom extends App.Controller
|
|||
@submitPost(e, ticket)
|
||||
return
|
||||
|
||||
|
||||
# verify if time accounting is active for ticket
|
||||
if false
|
||||
time_accounting_selector = @Config.get('time_accounting_selector')
|
||||
if !App.Ticket.selector(ticket, time_accounting_selector['condition'])
|
||||
@submitPost(e, ticket)
|
||||
return
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ class Index extends App.ControllerSubContent
|
|||
'change .js-timeAccountingSetting input': 'setTimeAccounting'
|
||||
'click .js-timePickerYear': 'setYear'
|
||||
'click .js-timePickerMonth': 'setMonth'
|
||||
'click .js-timeAccountingFilter': 'setFilter'
|
||||
'click .js-timeAccountingFilterReset': 'resetFilter'
|
||||
|
||||
elements:
|
||||
'.js-timeAccountingSetting input': 'timeAccountingSetting'
|
||||
|
@ -103,10 +105,12 @@ class Index extends App.ControllerSubContent
|
|||
{ name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: false, preview: false, action: false, hasChanged: false },
|
||||
]
|
||||
|
||||
new App.ControllerForm(
|
||||
filter_params = App.Setting.get('time_accounting_selector')
|
||||
@filter = new App.ControllerForm(
|
||||
el: @$('.js-selector')
|
||||
model:
|
||||
configure_attributes: configure_attributes,
|
||||
params: filter_params
|
||||
autofocus: true
|
||||
)
|
||||
|
||||
|
@ -128,6 +132,21 @@ class Index extends App.ControllerSubContent
|
|||
month: @month
|
||||
)
|
||||
|
||||
setFilter: (e) =>
|
||||
e.preventDefault()
|
||||
|
||||
# get form data
|
||||
params = @formParam(@filter.form)
|
||||
|
||||
# save filter settings
|
||||
App.Setting.set('time_accounting_selector', params, notify: true)
|
||||
|
||||
resetFilter: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
# save filter settings
|
||||
App.Setting.set('time_accounting_selector', {}, notify: true)
|
||||
|
||||
setTimeAccounting: (e) =>
|
||||
value = @timeAccountingSetting.prop('checked')
|
||||
App.Setting.set('time_accounting', value)
|
||||
|
|
|
@ -99,6 +99,9 @@ class App.Utils
|
|||
else
|
||||
'>'
|
||||
|
||||
@escapeRegExp: (str) ->
|
||||
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
|
||||
|
||||
# htmlEscaped = App.Utils.htmlEscape(rawText)
|
||||
@htmlEscape: (ascii) ->
|
||||
return ascii if !ascii
|
||||
|
|
|
@ -124,3 +124,103 @@ class App.Ticket extends App.Model
|
|||
# apply direct value changes
|
||||
else
|
||||
params.ticket[attributes[1]] = content.value
|
||||
|
||||
# check if selector is matching
|
||||
@selector: (ticket, selector) ->
|
||||
return true if _.isEmpty(selector)
|
||||
|
||||
for objectAttribute, condition of selector
|
||||
[objectName, attributeName] = objectAttribute.split('.')
|
||||
|
||||
# there is no article.subject so we take the title instead
|
||||
if objectAttribute == 'article.subject' && !ticket['article']['subject']
|
||||
objectName = 'ticket'
|
||||
attributeName = 'title'
|
||||
|
||||
# for new articles there is no created_by_id so we set the current user
|
||||
# if no id is given
|
||||
if objectAttribute == 'article.created_by_id' && !ticket['article']['created_by_id']
|
||||
ticket['article']['created_by_id'] = App.Session.get('id')
|
||||
|
||||
if objectName == 'ticket'
|
||||
object = ticket
|
||||
else
|
||||
object = ticket[objectName] || {}
|
||||
|
||||
return false if !@_selectorMatch(object, objectName, attributeName, condition)
|
||||
|
||||
return true
|
||||
|
||||
@_selectorConditionDate: (condition, operator) ->
|
||||
return if operator != '+' && operator != '-'
|
||||
|
||||
conditionValue = new Date()
|
||||
if condition['range'] == 'minute'
|
||||
conditionValue.setTime( eval( conditionValue.getTime() + operator + 60 * 1000 ) )
|
||||
else if condition['range'] == 'hour'
|
||||
conditionValue.setTime( eval( conditionValue.getTime() + operator + 60 * 60 * 1000 ) )
|
||||
else if condition['range'] == 'day'
|
||||
conditionValue.setTime( eval( conditionValue.getTime() + operator + 60 * 60 * 24 * 1000 ) )
|
||||
else if condition['range'] == 'month'
|
||||
conditionValue.setTime( eval( conditionValue.getTime() + operator + 60 * 60 * 30 * 1000 ) )
|
||||
else if condition['range'] == 'year'
|
||||
conditionValue.setTime( eval( conditionValue.getTime() + operator + 60 * 60 * 365 * 1000 ) )
|
||||
|
||||
conditionValue
|
||||
|
||||
@_selectorMatch: (object, objectName, attributeName, condition) ->
|
||||
conditionValue = condition.value
|
||||
conditionValue = '' if conditionValue == undefined
|
||||
objectValue = object[attributeName]
|
||||
objectValue = '' if objectValue == undefined
|
||||
|
||||
# take care about pre conditions
|
||||
if condition['pre_condition']
|
||||
[conditionType, conditionKey] = condition['pre_condition'].split('.')
|
||||
|
||||
if conditionType == 'current_user'
|
||||
conditionValue = App.Session.get(conditionKey)
|
||||
else if condition['pre_condition'] == 'not_set'
|
||||
conditionValue = ''
|
||||
|
||||
# prepare regex for contains conditions
|
||||
contains_regex = new RegExp(App.Utils.escapeRegExp(conditionValue.toString()), 'i')
|
||||
|
||||
# move value to array if it is not already
|
||||
if !_.isArray(objectValue)
|
||||
objectValue = [objectValue]
|
||||
# move value to array if it is not already
|
||||
if !_.isArray(conditionValue)
|
||||
conditionValue = [conditionValue]
|
||||
|
||||
result = false
|
||||
for loopObjectKey, loopObjectValue of objectValue
|
||||
for loopConditionKey, loopConditionValue of conditionValue
|
||||
if condition.operator == 'contains'
|
||||
result = true if objectValue.toString().match(contains_regex)
|
||||
else if condition.operator == 'contains not'
|
||||
result = true if !objectValue.toString().match(contains_regex)
|
||||
else if condition.operator == 'is'
|
||||
result = true if objectValue.toString().trim().toLowerCase() is loopConditionValue.toString().trim().toLowerCase()
|
||||
else if condition.operator == 'is not'
|
||||
result = true if objectValue.toString().trim().toLowerCase() isnt loopConditionValue.toString().trim().toLowerCase()
|
||||
else if condition.operator == 'after (absolute)'
|
||||
result = true if new Date(objectValue.toString()) > new Date(loopConditionValue.toString())
|
||||
else if condition.operator == 'before (absolute)'
|
||||
result = true if new Date(objectValue.toString()) < new Date(loopConditionValue.toString())
|
||||
else if condition.operator == 'before (relative)'
|
||||
loopConditionValue = @_selectorConditionDate(condition, '-')
|
||||
result = true if new Date(objectValue.toString()) < new Date(loopConditionValue.toString())
|
||||
else if condition.operator == 'within last (relative)'
|
||||
loopConditionValue = @_selectorConditionDate(condition, '-')
|
||||
result = true if new Date(objectValue.toString()) < new Date() && new Date(objectValue.toString()) > new Date(loopConditionValue.toString())
|
||||
else if condition.operator == 'after (relative)'
|
||||
loopConditionValue = @_selectorConditionDate(condition, '+')
|
||||
result = true if new Date(objectValue.toString()) > new Date(loopConditionValue.toString())
|
||||
else if condition.operator == 'within next (relative)'
|
||||
loopConditionValue = @_selectorConditionDate(condition, '+')
|
||||
result = true if new Date(objectValue.toString()) > new Date() && new Date(objectValue.toString()) < new Date(loopConditionValue.toString())
|
||||
else
|
||||
throw "Unknown operator: #{condition.operator}"
|
||||
|
||||
result
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
</div>
|
||||
<p><%- @T('Enable time accounting for following matching tickets.') %></p>
|
||||
<div class="js-selector"></div>
|
||||
<button type="submit" class="btn btn--primary js-timeAccountingFilter"><%- @T('Save') %></button>
|
||||
<button type="submit" class="btn btn--danger js-timeAccountingFilterReset"><%- @T('Reset') %></button>
|
||||
</div>
|
||||
|
||||
<div class="settings-entry">
|
||||
|
|
15
app/views/tests/ticket_selector.html.erb
Normal file
15
app/views/tests/ticket_selector.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
<link rel="stylesheet" href="/assets/tests/qunit-1.21.0.css">
|
||||
<script src="/assets/tests/qunit-1.21.0.js"></script>
|
||||
<script src="/assets/tests/ticket_selector.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<div id="qunit" class="u-dontfold"></div>
|
|
@ -14,6 +14,7 @@ Zammad::Application.routes.draw do
|
|||
match '/tests_form_searchable_select', to: 'tests#form_searchable_select', via: :get
|
||||
match '/tests_table', to: 'tests#table', via: :get
|
||||
match '/tests_html_utils', to: 'tests#html_utils', via: :get
|
||||
match '/tests_ticket_selector', to: 'tests#ticket_selector', via: :get
|
||||
match '/tests_taskbar', to: 'tests#taskbar', via: :get
|
||||
match '/tests/wait/:sec', to: 'tests#wait', via: :get
|
||||
match '/tests/unprocessable_entity', to: 'tests#error_unprocessable_entity', via: :get
|
||||
|
|
962
public/assets/tests/ticket_selector.js
Normal file
962
public/assets/tests/ticket_selector.js
Normal file
|
@ -0,0 +1,962 @@
|
|||
window.onload = function() {
|
||||
|
||||
var ticketData = {
|
||||
"number": "72008",
|
||||
"title": "asdfasdf",
|
||||
"group_id": 1,
|
||||
"owner_id": 6,
|
||||
"updated_by_id": 6,
|
||||
"created_by_id": 6,
|
||||
"customer_id": 6,
|
||||
"state_id": 4,
|
||||
"priority_id": 2,
|
||||
"created_at": "2017-02-09T09:16:56.192Z",
|
||||
"updated_at": "2017-02-09T09:16:56.192Z",
|
||||
"pending_time": "2017-02-09T09:16:56.192Z",
|
||||
"aaaaa": "1234568791",
|
||||
"anrede": "Herr",
|
||||
"asdf": "",
|
||||
"organization_id": 6,
|
||||
"organization": {
|
||||
"name": "harald test gmbh",
|
||||
"domain": "www.harald-ist-cool.de",
|
||||
"shared": true,
|
||||
"note": "<div>harald test gmbh</div>",
|
||||
"member_ids": [
|
||||
6,
|
||||
2
|
||||
],
|
||||
"active": true,
|
||||
"created_at": "2017-02-09T09:16:56.192Z",
|
||||
"updated_at": "2017-02-09T09:16:56.192Z",
|
||||
"domain_assignment": false,
|
||||
"updated_by_id": 6,
|
||||
"created_by_id": 6,
|
||||
"id": 6
|
||||
},
|
||||
"group": {
|
||||
"name": "Users",
|
||||
"assignment_timeout": null,
|
||||
"follow_up_possible": "reject",
|
||||
"follow_up_assignment": true,
|
||||
"email_address_id": 1,
|
||||
"signature_id": 1,
|
||||
"note": "Standard Group/Pool for Tickets.",
|
||||
"active": true,
|
||||
"updated_at": "2017-01-18T13:45:30.528Z",
|
||||
"id": 1
|
||||
},
|
||||
"owner": {
|
||||
"login": "-",
|
||||
"firstname": "-",
|
||||
"lastname": "",
|
||||
"email": "",
|
||||
"web": "",
|
||||
"password": "",
|
||||
"phone": "",
|
||||
"fax": "",
|
||||
"mobile": "",
|
||||
"street": "",
|
||||
"zip": "",
|
||||
"city": "",
|
||||
"country": "",
|
||||
"organization_id": null,
|
||||
"department": "",
|
||||
"note": "",
|
||||
"role_ids": [],
|
||||
"group_ids": [],
|
||||
"active": false,
|
||||
"updated_at": "2016-08-02T14:25:24.053Z",
|
||||
"address": "",
|
||||
"vip": false,
|
||||
"anrede": null,
|
||||
"asdf": null,
|
||||
"id": 1
|
||||
},
|
||||
"state": {
|
||||
"name": "closed",
|
||||
"note": null,
|
||||
"active": true,
|
||||
"id": 4
|
||||
},
|
||||
"priority": {
|
||||
"name": "2 normal",
|
||||
"note": null,
|
||||
"active": true,
|
||||
"updated_at": "2016-08-02T14:25:24.677Z",
|
||||
"id": 2
|
||||
},
|
||||
"article": {
|
||||
"from": "Test Master Agent",
|
||||
"to": "agent1@example.com",
|
||||
"cc": "agent1+cc@example.com",
|
||||
"body": "asdfasdfasdf<br><br><div data-signature=\"true\" data-signature-id=\"1\"> Test Master Agent<br><br>--<br> Super Support - Waterford Business Park<br> 5201 Blue Lagoon Drive - 8th Floor & 9th Floor - Miami, 33126 USA<br> Email: hot@example.com - Web: http://www.example.com/<br>--</div>",
|
||||
"content_type": "text/html",
|
||||
"ticket_id": "2",
|
||||
"type_id": 1,
|
||||
"sender_id": 1,
|
||||
"internal": false,
|
||||
"in_reply_to": "<20170217100622.2.152971@zammad.example.com>",
|
||||
"form_id": "326044216"
|
||||
},
|
||||
"customer": {
|
||||
"login": "hc@zammad.com",
|
||||
"firstname": "Harald",
|
||||
"lastname": "Customer",
|
||||
"email": "hc@zammad.com",
|
||||
"web": "zammad.com",
|
||||
"password": "",
|
||||
"phone": "1234567894",
|
||||
"fax": "",
|
||||
"mobile": "",
|
||||
"street": "",
|
||||
"zip": "",
|
||||
"city": "",
|
||||
"country": "",
|
||||
"organization_id": 6,
|
||||
"created_by_id": 6,
|
||||
"updated_by_id": 6,
|
||||
"department": "",
|
||||
"note": "",
|
||||
"role_ids": [
|
||||
3
|
||||
],
|
||||
"group_ids": [],
|
||||
"active": true,
|
||||
"created_at": "2017-02-09T09:16:56.192Z",
|
||||
"updated_at": "2017-02-09T09:16:56.192Z",
|
||||
"address": "Walter-Gropius-Straße 17, 80807 München, Germany",
|
||||
"web": "www.harald-ist-cool.de",
|
||||
"vip": false,
|
||||
"id": 434
|
||||
},
|
||||
"escalation_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_agent_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_agent_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_customer_at": "2017-02-09T09:16:56.192Z",
|
||||
"first_response_at": "2017-02-09T09:16:56.192Z",
|
||||
"close_at": "2017-02-09T09:16:56.192Z",
|
||||
"id": 8
|
||||
};
|
||||
|
||||
var sessionData = {
|
||||
"login": "hh@zammad.com",
|
||||
"firstname": "Harald",
|
||||
"lastname": "Habebe",
|
||||
"email": "hh@zammad.com",
|
||||
"web": "",
|
||||
"password": "",
|
||||
"phone": "",
|
||||
"fax": "",
|
||||
"mobile": "",
|
||||
"street": "",
|
||||
"zip": "",
|
||||
"city": "",
|
||||
"country": "",
|
||||
"organization_id": 6,
|
||||
"department": "",
|
||||
"note": "",
|
||||
"role_ids": [
|
||||
1,
|
||||
2,
|
||||
5,
|
||||
6,
|
||||
4
|
||||
],
|
||||
"group_ids": [
|
||||
1
|
||||
],
|
||||
"active": true,
|
||||
"updated_at": "2017-02-09T09:17:04.770Z",
|
||||
"address": "",
|
||||
"vip": false,
|
||||
"anrede": "",
|
||||
"asdf": "",
|
||||
"id": 6
|
||||
};
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------------------
|
||||
* Test functions
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
var testContains = function (key, value, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "contains",
|
||||
"value": value
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "contains not",
|
||||
"value": value
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
};
|
||||
|
||||
var testIs = function (key, value, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"value": value
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"value": value
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
};
|
||||
|
||||
var testPreConditionUser = function (key, specificValue, ticket, session) {
|
||||
App.Session.set(sessionData);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "current_user.id",
|
||||
"value": "",
|
||||
"value_completion": ""
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "current_user.id",
|
||||
"value": "",
|
||||
"value_completion": ""
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "not_set",
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "not_set",
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
var testPreConditionOrganization = function (key, specificValue, ticket, session) {
|
||||
App.Session.set(sessionData);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "current_user.organization_id",
|
||||
"value": "",
|
||||
"value_completion": ""
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "current_user.organization_id",
|
||||
"value": "",
|
||||
"value_completion": ""
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "specific",
|
||||
"value": specificValue,
|
||||
"value_completion": "Nicole Braun <nicole.braun@zammad.org>"
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is",
|
||||
"pre_condition": "not_set",
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "is not",
|
||||
"pre_condition": "not_set",
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
var testTime = function (key, value, ticket) {
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() - 1 ) ).toISOString();
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "after (absolute)",
|
||||
"value": compareDate
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() + 1 ) ).toISOString();
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "after (absolute)",
|
||||
"value": compareDate
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() - 1 ) ).toISOString();
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "before (absolute)",
|
||||
"value": compareDate
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, false, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() + 1 ) ).toISOString();
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "before (absolute)",
|
||||
"value": compareDate
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() + 2 ) ).toISOString();
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "before (relative)",
|
||||
"value": 1,
|
||||
"range": "hour"
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
var testTimeBeforeRelative = function (key, value, range, expectedResult, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "before (relative)",
|
||||
"value": value,
|
||||
"range": range
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
var testTimeAfterRelative = function (key, value, range, expectedResult, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "after (relative)",
|
||||
"value": value,
|
||||
"range": range
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
var testTimeWithinNextRelative = function (key, value, range, expectedResult, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "within next (relative)",
|
||||
"value": value,
|
||||
"range": range
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
var testTimeWithinLastRelative = function (key, value, range, expectedResult, ticket) {
|
||||
setting = {
|
||||
"condition": {
|
||||
[key]: {
|
||||
"operator": "within last (relative)",
|
||||
"value": value,
|
||||
"range": range
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
/*
|
||||
* ------------------------------------------------------------------------
|
||||
* Field tests
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
test("ticket number", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('ticket.number', '72', ticket);
|
||||
});
|
||||
|
||||
test("ticket title", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('ticket.title', 'asd', ticket);
|
||||
});
|
||||
|
||||
test("ticket customer_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
App.Session.set(sessionData);
|
||||
|
||||
testPreConditionUser('ticket.customer_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket organization_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('ticket.organization_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket group_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('ticket.group_id', ['1'], ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket owner_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
App.Session.set(sessionData);
|
||||
|
||||
testPreConditionUser('ticket.owner_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket state_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('ticket.state_id', ['4'], ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket pending_time", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.pending_time', ticket.pending_time, ticket);
|
||||
|
||||
// -------------------------
|
||||
// BEFORE TIME
|
||||
// -------------------------
|
||||
|
||||
// hour
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
// day
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'day', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 48 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'day', true, ticket);
|
||||
|
||||
// year
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'year', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 365 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'year', true, ticket);
|
||||
|
||||
// -------------------------
|
||||
// AFTER TIME
|
||||
// -------------------------
|
||||
|
||||
// hour
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
// day
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'day', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 48 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'day', true, ticket);
|
||||
|
||||
// year
|
||||
ticket.pending_time = new Date().toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'year', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 365 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'year', true, ticket);
|
||||
|
||||
|
||||
// -------------------------
|
||||
// WITHIN LAST TIME
|
||||
// -------------------------
|
||||
|
||||
// hour
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 0.5 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinLastRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinLastRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
// -------------------------
|
||||
// WITHIN NEXT TIME
|
||||
// -------------------------
|
||||
|
||||
// hour
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 0.5 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinNextRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000 );
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinNextRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
});
|
||||
|
||||
test("ticket priority_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('ticket.priority_id', ['2'], ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket escalation_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.escalation_at', ticket.escalation_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket last_contact_agent_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.last_contact_agent_at', ticket.last_contact_agent_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket last_contact_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.last_contact_at', ticket.last_contact_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket last_contact_customer_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.last_contact_customer_at', ticket.last_contact_customer_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket first_response_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.first_response_at', ticket.first_response_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket close_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.close_at', ticket.close_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket created_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
App.Session.set(sessionData);
|
||||
|
||||
testPreConditionUser('ticket.created_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket created_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.created_at', ticket.created_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket updated_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('ticket.updated_at', ticket.updated_at, ticket);
|
||||
});
|
||||
|
||||
test("ticket updated_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
App.Session.set(sessionData);
|
||||
|
||||
testPreConditionUser('ticket.updated_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("article from", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('article.from', 'Master', ticket);
|
||||
});
|
||||
|
||||
test("article to", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('article.to', 'agent1', ticket);
|
||||
});
|
||||
|
||||
test("article cc", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('article.cc', 'agent1+cc', ticket);
|
||||
});
|
||||
|
||||
test("article subject", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('article.subject', 'asdf', ticket);
|
||||
});
|
||||
|
||||
test("article type_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('article.type_id', ['1'], ticket);
|
||||
});
|
||||
|
||||
test("article sender_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('article.sender_id', ['1'], ticket);
|
||||
});
|
||||
|
||||
test("article internal", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('article.internal', ['false'], ticket);
|
||||
});
|
||||
|
||||
test("article created_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('article.created_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("customer login", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.login', 'hc', ticket);
|
||||
});
|
||||
|
||||
test("customer firstname", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.firstname', 'Harald', ticket);
|
||||
});
|
||||
|
||||
test("customer lastname", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.lastname', 'Customer', ticket);
|
||||
});
|
||||
|
||||
test("customer email", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.email', 'hc', ticket);
|
||||
});
|
||||
|
||||
test("customer organization_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionOrganization('customer.organization_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("customer created_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('customer.created_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("customer created_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('customer.created_at', ticket.customer.created_at, ticket);
|
||||
});
|
||||
|
||||
test("customer updated_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('customer.updated_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("customer missing_field", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.missing_field', '', ticket);
|
||||
});
|
||||
|
||||
test("customer web", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('customer.web', 'cool', ticket);
|
||||
});
|
||||
|
||||
test("organization name", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('organization.name', 'gmbh', ticket);
|
||||
});
|
||||
|
||||
test("organization shared", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('organization.shared', true, ticket);
|
||||
});
|
||||
|
||||
test("organization created_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('organization.created_by_id', 6, ticket);
|
||||
});
|
||||
|
||||
test("organization updated_by_id", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionUser('organization.updated_by_id', 6, ticket);
|
||||
});
|
||||
|
||||
test("organization created_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('organization.created_at', ticket.organization.created_at, ticket);
|
||||
});
|
||||
|
||||
test("organization updated_at", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testTime('organization.updated_at', ticket.organization.updated_at, ticket);
|
||||
});
|
||||
|
||||
test("organization domain_assignment", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testIs('organization.domain_assignment', false, ticket);
|
||||
});
|
||||
|
||||
test("organization domain", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testContains('organization.domain', 'cool', ticket);
|
||||
});
|
||||
}
|
|
@ -34,6 +34,13 @@ class AAbUnitTest < TestCase
|
|||
css: '.result .failed',
|
||||
value: '0',
|
||||
)
|
||||
|
||||
location(url: browser_url + '/tests_ticket_selector')
|
||||
sleep 8
|
||||
match(
|
||||
css: '.result .failed',
|
||||
value: '0',
|
||||
)
|
||||
end
|
||||
|
||||
def test_form
|
||||
|
|
Loading…
Reference in a new issue