diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.coffee
index aeeb9de0a..0b170b2cc 100644
--- a/app/assets/javascripts/app/controllers/_application_controller_form.coffee
+++ b/app/assets/javascripts/app/controllers/_application_controller_form.coffee
@@ -410,8 +410,8 @@ class App.ControllerForm extends App.Controller
for key in array
# check if item is-hidden and should not be used
- if lookupForm.find('[name="' + key.name + '"]').hasClass('is-hidden')
- param[key.name] = undefined
+ if lookupForm.find('[name="' + key.name + '"]').hasClass('is-hidden') || lookupForm.find('div[data-name="' + key.name + '"]').hasClass('is-hidden')
+ delete param[key.name]
continue
# collect all params, push it to an array if already exists
diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
index b12765ee8..7aaef98a4 100644
--- a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
+++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee
@@ -1,6 +1,6 @@
# coffeelint: disable=camel_case_classes
class App.UiElement.ticket_perform_action
- @defaults: ->
+ @defaults: (attribute) ->
defaults = ['ticket.state_id']
groups =
@@ -8,31 +8,40 @@ class App.UiElement.ticket_perform_action
name: 'Ticket'
model: 'Ticket'
+ if attribute.notification
+ groups.notification =
+ name: 'Notification'
+ model: 'Notification'
+
# megre config
elements = {}
for groupKey, groupMeta of groups
- for row in App[groupMeta.model].configure_attributes
+ if !App[groupMeta.model]
+ elements["#{groupKey}.email"] = { name: 'email', display: 'Email' }
+ else
- # ignore passwords and relations
- if row.type isnt 'password' && row.name.substr(row.name.length-4,4) isnt '_ids'
+ for row in App[groupMeta.model].configure_attributes
- # ignore readonly attributes
- if !row.readonly
- config = _.clone(row)
- if config.tag is 'tag'
- config.operator = ['add', 'remove']
- elements["#{groupKey}.#{config.name}"] = config
+ # ignore passwords and relations
+ if row.type isnt 'password' && row.name.substr(row.name.length-4,4) isnt '_ids'
+
+ # ignore readonly attributes
+ if !row.readonly
+ config = _.clone(row)
+ if config.tag is 'tag'
+ config.operator = ['add', 'remove']
+ elements["#{groupKey}.#{config.name}"] = config
[defaults, groups, elements]
@render: (attribute, params = {}) ->
- [defaults, groups, elements] = @defaults()
+ [defaults, groups, elements] = @defaults(attribute)
selector = @buildAttributeSelector(groups, elements)
# return item
- item = $( App.view('generic/ticket_perform_action')( attribute: attribute ) )
+ item = $( App.view('generic/ticket_perform_action/index')( attribute: attribute ) )
item.find('.js-attributeSelector').prepend(selector)
# add filter
@@ -65,8 +74,6 @@ class App.UiElement.ticket_perform_action
selectorExists = false
for groupAndAttribute, meta of params[attribute.name]
selectorExists = true
- value = meta.value
- operator = meta.operator
# get selector rows
elementFirst = item.find('.js-filterElement').first()
@@ -149,7 +156,19 @@ class App.UiElement.ticket_perform_action
if groupAndAttribute
elementRow.find('.js-attributeSelector select').val(groupAndAttribute)
- @buildOperator(elementFull, elementRow, groupAndAttribute, elements, meta, attribute)
+ if groupAndAttribute is 'notification.email'
+ elementRow.find('.js-setAttribute').html('')
+ @buildRecipientList(elementFull, elementRow, groupAndAttribute, elements, meta, attribute)
+ else
+ elementRow.find('.js-setNotification').html('')
+ if !elementRow.find('.js-setAttribute div').get(0)
+ attributeSelectorElement = $( App.view('generic/ticket_perform_action/attribute_selector')(
+ attribute: attribute
+ name: name
+ meta: meta || {}
+ ))
+ elementRow.find('.js-setAttribute').html(attributeSelectorElement)
+ @buildOperator(elementFull, elementRow, groupAndAttribute, elements, meta, attribute)
@buildOperator: (elementFull, elementRow, groupAndAttribute, elements, meta, attribute) ->
currentOperator = elementRow.find('.js-operator option:selected').attr('value')
@@ -160,9 +179,7 @@ class App.UiElement.ticket_perform_action
name = "#{attribute.name}::#{groupAndAttribute}::operator"
selection = $(" ")
-
attributeConfig = elements[groupAndAttribute]
-
if !attributeConfig.operator
elementRow.find('.js-operator').addClass('hide')
else
@@ -282,7 +299,36 @@ class App.UiElement.ticket_perform_action
elementRow.find('.js-value').removeClass('hide').html(item)
+ @buildRecipientList: (elementFull, elementRow, groupAndAttribute, elements, meta, attribute) ->
+ return if elementRow.find('.js-setNotification .js-body').get(0)
+
+ options =
+ 'ticket_owner': 'Owner'
+ 'ticket_customer': 'Customer'
+ 'ticket_agents': 'All Agents'
+
+ name = "#{attribute.name}::notification.email"
+
+ selection = $(" ")
+ for key, value of options
+ selected = ''
+ if key is meta.recipient
+ selected = 'selected="selected"'
+ selection.append("#{App.i18n.translateInline(value)} ")
+
+ notificationElement = $( App.view('generic/ticket_perform_action/notification_email')(
+ attribute: attribute
+ name: name
+ meta: meta || {}
+ ))
+ notificationElement.find('.js-recipient select').replaceWith(selection)
+ notificationElement.find('.js-body div[contenteditable="true"]').ce(
+ mode: 'richtext'
+ placeholder: 'message'
+ maxlength: 2000
+ )
+ elementRow.find('.js-setNotification').html(notificationElement)
@humanText: (condition) ->
none = App.i18n.translateContent('No filter.')
diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee
index 05a822959..18a0e6f2e 100644
--- a/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee
+++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee
@@ -1,12 +1,15 @@
# coffeelint: disable=camel_case_classes
class App.UiElement.ticket_selector
- @defaults: ->
+ @defaults: (attribute) ->
defaults = ['ticket.state_id']
groups =
ticket:
name: 'Ticket'
model: 'Ticket'
+ #article:
+ # name: 'Article'
+ # model: 'TicketArticle'
customer:
name: 'Customer'
model: 'User'
@@ -25,13 +28,25 @@ class App.UiElement.ticket_selector
'_id$': ['is', 'is not']
'_ids$': ['is', 'is not']
- # megre config
+ # merge config
elements = {}
+
+ if attribute.action
+ elements['ticket.action'] =
+ name: 'action'
+ display: 'Action'
+ tag: 'select'
+ null: false
+ options:
+ create: 'created'
+ update: 'updated'
+ operator: ['is', 'is not']
+
for groupKey, groupMeta of groups
for row in App[groupMeta.model].configure_attributes
# ignore passwords and relations
- if row.type isnt 'password' && row.name.substr(row.name.length-4,4) isnt '_ids'
+ if row.type isnt 'password' && row.name.substr(row.name.length-4,4) isnt '_ids' && row.searchable isnt false
config = _.clone(row)
for operatorRegEx, operator of operators_type
myRegExp = new RegExp(operatorRegEx, 'i')
@@ -47,15 +62,12 @@ class App.UiElement.ticket_selector
@render: (attribute, params = {}) ->
- [defaults, groups, elements] = @defaults()
+ [defaults, groups, elements] = @defaults(attribute)
selector = @buildAttributeSelector(groups, elements)
- search = =>
- @preview(item)
-
# return item
- item = $( App.view('generic/ticket_selector')( attribute: attribute ) )
+ item = $( App.view('generic/ticket_selector')(attribute: attribute) )
item.find('.js-attributeSelector').prepend(selector)
# add filter
@@ -65,7 +77,8 @@ class App.UiElement.ticket_selector
element.after(elementClone)
elementClone.find('.js-attributeSelector select').trigger('change')
@updateAttributeSelectors(item)
- @preview(item)
+ if attribute.preview isnt false
+ @preview(item)
)
# remove filter
@@ -73,7 +86,8 @@ class App.UiElement.ticket_selector
return if $(e.currentTarget).hasClass('is-disabled')
$(e.target).closest('.js-filterElement').remove()
@updateAttributeSelectors(item)
- @preview(item)
+ if attribute.preview isnt false
+ @preview(item)
)
# build inital params
@@ -108,23 +122,6 @@ class App.UiElement.ticket_selector
elementLast.after(elementClone)
item.find('.js-filterElement').first().remove()
- triggerSearch = ->
- item.find('.js-previewCounterContainer').addClass('hide')
- item.find('.js-previewLoader').removeClass('hide')
- App.Delay.set(
- search,
- 600,
- 'preview',
- )
-
- # bind for preview
- item.on('change', 'select.form-control', (e) ->
- triggerSearch()
- )
- item.on('change keyup', 'input.form-control', (e) ->
- triggerSearch()
- )
-
# change attribute selector
item.find('.js-attributeSelector select').bind('change', (e) =>
elementRow = $(e.target).closest('.js-filterElement')
@@ -140,6 +137,27 @@ class App.UiElement.ticket_selector
@buildOperator(item, elementRow, groupAndAttribute, elements, {}, attribute)
)
+ # bind for preview
+ if attribute.preview isnt false
+ search = =>
+ @preview(item)
+
+ triggerSearch = ->
+ item.find('.js-previewCounterContainer').addClass('hide')
+ item.find('.js-previewLoader').removeClass('hide')
+ App.Delay.set(
+ search,
+ 600,
+ 'preview',
+ )
+
+ item.on('change', 'select', (e) ->
+ triggerSearch()
+ )
+ item.on('change keyup', 'input', (e) ->
+ triggerSearch()
+ )
+
item
@preview: (item) ->
diff --git a/app/assets/javascripts/app/controllers/trigger.coffee b/app/assets/javascripts/app/controllers/trigger.coffee
index 4376f2d6f..251143ccf 100644
--- a/app/assets/javascripts/app/controllers/trigger.coffee
+++ b/app/assets/javascripts/app/controllers/trigger.coffee
@@ -10,7 +10,6 @@ class Index extends App.ControllerContent
id: @id
genericObject: 'Trigger'
defaultSortBy: 'name'
- #groupBy: 'role'
pageData:
title: 'Triggers'
home: 'triggers'
diff --git a/app/assets/javascripts/app/models/trigger.coffee b/app/assets/javascripts/app/models/trigger.coffee
index 2c9352d60..94f2d1d48 100644
--- a/app/assets/javascripts/app/models/trigger.coffee
+++ b/app/assets/javascripts/app/models/trigger.coffee
@@ -4,9 +4,8 @@ class App.Trigger extends App.Model
@url: @apiPath + '/triggers'
@configure_attributes = [
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, null: false },
- { name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: false },
- { name: 'perform', display: 'Execute changes on objects', tag: 'ticket_perform_action', null: true },
- { name: 'disable_notiifcation', display: 'Disable Notifications', tag: 'boolean', default: true },
+ { name: 'condition', display: 'Conditions for effected objects', tag: 'ticket_selector', null: false, preview: false, action: true },
+ { name: 'perform', display: 'Execute changes on objects', tag: 'ticket_perform_action', null: true, notification: true },
{ name: 'active', display: 'Active', tag: 'active', default: true },
{ name: 'updated_at', display: 'Updated', tag: 'datetime', readonly: 1 },
]
@@ -14,8 +13,9 @@ class App.Trigger extends App.Model
@configure_overview = [
'name',
]
-
+ ###
@description = '''
Trigger are....
-'''
\ No newline at end of file
+'''
+ ###
diff --git a/app/assets/javascripts/app/views/generic/ticket_perform_action/attribute_selector.jst.eco b/app/assets/javascripts/app/views/generic/ticket_perform_action/attribute_selector.jst.eco
new file mode 100644
index 000000000..2dc95049a
--- /dev/null
+++ b/app/assets/javascripts/app/views/generic/ticket_perform_action/attribute_selector.jst.eco
@@ -0,0 +1,15 @@
+
+
<%- @T('Preview') %> ? <%- @T('matches') %>
\ No newline at end of file
diff --git a/app/models/job.rb b/app/models/job.rb
index 3eedc75ff..dff007a82 100644
--- a/app/models/job.rb
+++ b/app/models/job.rb
@@ -44,21 +44,7 @@ class Job < ApplicationModel
# use transaction
ActiveRecord::Base.transaction do
UserInfo.current_user_id = 1
-
- 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
+ ticket.perform_changes(job.perform, 'job')
# execute object transaction
Observer::Transaction.commit(
diff --git a/app/models/observer/ticket/article/communicate_email/background_job.rb b/app/models/observer/ticket/article/communicate_email/background_job.rb
index 5c9933793..9ba80b313 100644
--- a/app/models/observer/ticket/article/communicate_email/background_job.rb
+++ b/app/models/observer/ticket/article/communicate_email/background_job.rb
@@ -19,6 +19,12 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
channel = ticket.group.email_address.channel
+ notification = false
+ sender = Ticket::Article::Sender.lookup(id: record.sender_id)
+ if sender['name'] == 'System'
+ notification = true
+ end
+
# get linked channel and send
message = channel.deliver(
{
@@ -32,7 +38,8 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
content_type: record.content_type,
body: record.body,
attachments: record.attachments
- }
+ },
+ notification
)
# store mail plain
diff --git a/app/models/observer/ticket/article/fillup_from_email.rb b/app/models/observer/ticket/article/fillup_from_email.rb
index 01f4927ea..d28fa108a 100644
--- a/app/models/observer/ticket/article/fillup_from_email.rb
+++ b/app/models/observer/ticket/article/fillup_from_email.rb
@@ -41,7 +41,7 @@ class Observer::Ticket::Article::FillupFromEmail < ActiveRecord::Observer
raise "No email address found for group '#{ticket.group.name}'"
end
system_sender = "#{email_address.realname} <#{email_address.email}>"
- if Setting.get('ticket_define_email_from') == 'AgentNameSystemAddressName'
+ if record.created_by_id != 1 && Setting.get('ticket_define_email_from') == 'AgentNameSystemAddressName'
seperator = Setting.get('ticket_define_email_from_seperator')
sender = User.find(record.created_by_id)
record.from = "#{sender.firstname} #{sender.lastname} #{seperator} #{system_sender}"
diff --git a/app/models/observer/transaction.rb b/app/models/observer/transaction.rb
index 26437c192..2c2d2a1bd 100644
--- a/app/models/observer/transaction.rb
+++ b/app/models/observer/transaction.rb
@@ -26,15 +26,41 @@ class Observer::Transaction < ActiveRecord::Observer
# reset buffer
EventBuffer.reset('transaction')
+ # get asyn backends
+ sync_backends = []
+ Setting.where(area: 'Transaction::Backend::Sync').order(:name).each {|setting|
+ backend = Setting.get(setting.name)
+ sync_backends.push Kernel.const_get(backend)
+ }
+
# get uniq objects
list_objects = get_uniq_changes(list)
list_objects.each {|_object, objects|
objects.each {|_id, item|
+
+ # execute sync backends
+ sync_backends.each {|backend|
+ execute_singel_backend(backend, item, params)
+ }
+
+ # execute async backends
Delayed::Job.enqueue(Transaction::BackgroundJob.new(item, params))
}
}
end
+ def self.execute_singel_backend(backend, item, params)
+ Rails.logger.error "Execute singel backend #{backend}"
+ begin
+ UserInfo.current_user_id = nil
+ integration = backend.new(item, params)
+ integration.perform
+ rescue => e
+ Rails.logger.error 'ERROR: ' + backend.inspect
+ Rails.logger.error 'ERROR: ' + e.inspect
+ end
+ end
+
=begin
result = get_uniq_changes(events)
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 0efb6a876..2dc08abcc 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -13,12 +13,16 @@ class Tag < ApplicationModel
# lookups
if data[:object]
- tag_object_id = tag_object_lookup( data[:object] )
+ tag_object_id = tag_object_lookup(data[:object])
end
if data[:item]
- tag_item_id = tag_item_lookup( data[:item] )
+ tag_item_id = tag_item_lookup(data[:item].strip)
end
+ # return in duplicate
+ current_tags = tag_list(data)
+ return true if current_tags.include?(data[:item].downcase.strip)
+
# create history
Tag.create(
tag_object_id: tag_object_id,
@@ -33,10 +37,10 @@ class Tag < ApplicationModel
# lookups
if data[:object]
- tag_object_id = tag_object_lookup( data[:object] )
+ tag_object_id = tag_object_lookup(data[:object])
end
if data[:item]
- tag_item_id = tag_item_lookup( data[:item] )
+ tag_item_id = tag_item_lookup(data[:item].strip)
end
# create history
@@ -49,80 +53,76 @@ class Tag < ApplicationModel
true
end
- def self.tag_list( data )
- tag_object_id_requested = tag_object_lookup( data[:object] )
+ def self.tag_list(data)
+ tag_object_id_requested = tag_object_lookup(data[:object])
tag_search = Tag.where(
tag_object_id: tag_object_id_requested,
o_id: data[:o_id],
)
tags = []
tag_search.each {|tag|
- tags.push tag_item_lookup_id( tag.tag_item_id )
+ tags.push tag_item_lookup_id(tag.tag_item_id)
}
tags
end
- def self.tag_item_lookup_id( id )
+ def self.tag_item_lookup_id(id)
# use cache
- return @@cache_item[ id ] if @@cache_item[ id ]
+ return @@cache_item[id] if @@cache_item[id]
# lookup
tag_item = Tag::Item.find(id)
- @@cache_item[ id ] = tag_item.name
+ @@cache_item[id] = tag_item.name
tag_item.name
end
- def self.tag_item_lookup( name )
+ def self.tag_item_lookup(name)
name = name.downcase
# use cache
- return @@cache_item[ name ] if @@cache_item[ name ]
+ return @@cache_item[name] if @@cache_item[name]
# lookup
- tag_item = Tag::Item.find_by( name: name )
+ tag_item = Tag::Item.find_by(name: name)
if tag_item
- @@cache_item[ name ] = tag_item.id
+ @@cache_item[name] = tag_item.id
return tag_item.id
end
# create
- tag_item = Tag::Item.create(
- name: name
- )
- @@cache_item[ name ] = tag_item.id
+ tag_item = Tag::Item.create(name: name)
+ @@cache_item[name] = tag_item.id
tag_item.id
end
- def self.tag_object_lookup_id( id )
+ def self.tag_object_lookup_id(id)
# use cache
- return @@cache_object[ id ] if @@cache_object[ id ]
+ return @@cache_object[id] if @@cache_object[id]
# lookup
tag_object = Tag::Object.find(id)
- @@cache_object[ id ] = tag_object.name
+ @@cache_object[id] = tag_object.name
tag_object.name
end
- def self.tag_object_lookup( name )
+ def self.tag_object_lookup(name)
# use cache
- return @@cache_object[ name ] if @@cache_object[ name ]
+ return @@cache_object[name] if @@cache_object[name]
# lookup
- tag_object = Tag::Object.find_by( name: name )
+ tag_object = Tag::Object.find_by(name: name)
if tag_object
- @@cache_object[ name ] = tag_object.id
+ @@cache_object[name] = tag_object.id
return tag_object.id
end
# create
- tag_object = Tag::Object.create(
- name: name
- )
- @@cache_object[ name ] = tag_object.id
+ tag_object = Tag::Object.create(name: name)
+ @@cache_object[name] = tag_object.id
tag_object.id
end
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index 2f390f26d..22b0053bb 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -457,6 +457,9 @@ condition example
elsif selector[0] == 'owner'
tables += ', users owners'
query += 'tickets.owner_id = owners.id'
+ elsif selector[0] == 'article'
+ tables += ', ticket_articles articles'
+ query += 'tickets.id = articles.ticket_id'
else
raise "invalid selector #{attribute.inspect}->#{selector.inspect}"
end
@@ -630,6 +633,129 @@ condition example
=begin
+perform changes on ticket
+
+ ticket.perform_changes({}, 'trigger')
+
+=end
+
+ def perform_changes(perform, log)
+ logger.debug "Perform #{log} #{perform.inspect} on Ticket.find(#{id})"
+ changed = false
+ perform.each do |key, value|
+ (object_name, attribute) = key.split('.', 2)
+ raise "Unable to update object #{object_name}.#{attribute}, only can update tickets and send notifications!" if object_name != 'ticket' && object_name != 'notification'
+
+ # send notification
+ if object_name == 'notification'
+ recipients = []
+ if value['recipient'] == 'ticket_customer'
+ recipients.push User.lookup(id: customer_id)
+ elsif value['recipient'] == 'ticket_owner'
+ recipients.push User.lookup(id: owner_id)
+ elsif value['recipient'] == 'ticket_agents'
+ recipients = recipients.concat(agent_of_group)
+ else
+ logger.error "Unknown email notification recipient '#{value['recipient']}'"
+ next
+ end
+ recipient_string = ''
+ recipient_already = {}
+ recipients.each {|user|
+ next if !user.email
+ next if user.email !~ /@/
+ email = user.email.downcase.strip
+ next if recipient_already[email]
+ recipient_already[email] = true
+ if recipient_string != ''
+ recipient_string += ', '
+ end
+ recipient_string += email
+ }
+ next if recipient_string == ''
+ group = self.group
+ next if !group
+ email_address = group.email_address
+ next if !email_address
+ next if !email_address.channel_id
+
+ objects = {
+ ticket: self,
+ article: articles.last,
+ #recipient: user,
+ #changes: changes,
+ }
+
+ # get subject
+ value['subject'].gsub!(/\#\{(.+?)\}/, '<%= d "\\1", false %>')
+ subject = NotificationFactory::Mailer.template(
+ templateInline: value['subject'],
+ locale: 'en-en',
+ objects: objects,
+ )
+ subject = subject_build(subject)
+
+ value['body'].gsub!(/\#\{(.+?)\}/, '<%= d "\\1", true %>')
+ body = NotificationFactory::Mailer.template(
+ templateInline: value['body'],
+ locale: 'en-en',
+ objects: objects,
+ )
+ Ticket::Article.create(
+ ticket_id: id,
+ #from: 'some_sender@example.com',
+ to: recipient_string,
+ subject: subject,
+ content_type: 'text/html',
+ body: body,
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'System'),
+ type: Ticket::Article::Type.find_by(name: 'email'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ next
+ end
+
+ # update tags
+ if key == 'ticket.tags'
+ next if value['value'].empty?
+ tags = value['value'].split(/,/)
+ if value['operator'] == 'add'
+ tags.each {|tag|
+ Tag.tag_add(
+ object: 'Ticket',
+ o_id: id,
+ item: tag,
+ )
+ }
+ elsif value['operator'] == 'remove'
+ tags.each {|tag|
+ Tag.tag_remove(
+ object: 'Ticket',
+ o_id: id,
+ item: tag,
+ )
+ }
+ else
+ logger.error "Unknown #{attribute} operator #{value['operator']}"
+ end
+ next
+ end
+
+ # update ticket
+ next if self[attribute].to_s == value['value'].to_s
+ changed = true
+
+ self[attribute] = value['value']
+ logger.debug "set #{object_name}.#{attribute} = #{value['value'].inspect}"
+ end
+ return if !changed
+ save
+ end
+
+=begin
+
get all email references headers of a ticket, to exclude some, parse it as array into method
references = ticket.get_references
diff --git a/app/models/ticket/subject.rb b/app/models/ticket/subject.rb
index 4c946891a..fb0044219 100644
--- a/app/models/ticket/subject.rb
+++ b/app/models/ticket/subject.rb
@@ -29,7 +29,7 @@ returns
# right position
if Setting.get('ticket_hook_position') == 'right'
- return subject + " [#{ticket_hook}#{ticket_hook_divider}#{number}] "
+ return subject + " [#{ticket_hook}#{ticket_hook_divider}#{number}]"
end
# left position
diff --git a/app/models/transaction/background_job.rb b/app/models/transaction/background_job.rb
index 9bde30da4..488bd271e 100644
--- a/app/models/transaction/background_job.rb
+++ b/app/models/transaction/background_job.rb
@@ -22,16 +22,9 @@ class Transaction::BackgroundJob
end
def perform
- Setting.where(area: 'Transaction::Backend').order(:name).each {|setting|
- backend = Setting.get(setting.name)
- begin
- UserInfo.current_user_id = nil
- integration = Kernel.const_get(backend).new(@item, @params)
- integration.perform
- rescue => e
- Rails.logger.error 'ERROR: ' + setting.inspect
- Rails.logger.error 'ERROR: ' + e.inspect
- end
+ Setting.where(area: 'Transaction::Backend::Async').order(:name).each {|setting|
+ backend = Kernel.const_get(Setting.get(setting.name))
+ Observer::Transaction.execute_singel_backend(backend, @item, @params)
}
end
diff --git a/app/models/transaction/trigger.rb b/app/models/transaction/trigger.rb
new file mode 100644
index 000000000..1824097b8
--- /dev/null
+++ b/app/models/transaction/trigger.rb
@@ -0,0 +1,77 @@
+# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
+
+class Transaction::Trigger
+
+=begin
+ {
+ object: 'Ticket',
+ type: 'update',
+ object_id: 123,
+ via_web: true,
+ changes: {
+ 'attribute1' => [before, now],
+ 'attribute2' => [before, now],
+ }
+ user_id: 123,
+ },
+=end
+
+ def initialize(item, params = {})
+ @item = item
+ @params = params
+ end
+
+ def perform
+
+ # return if we run import mode
+ return if Setting.get('import_mode')
+
+ return if @item[:object] != 'Ticket'
+
+ triggers = Trigger.where(active: true)
+ return if triggers.empty?
+
+ ticket = Ticket.lookup(id: @item[:object_id])
+ return if !ticket
+ if @item[:article_id]
+ article = Ticket::Article.lookup(id: @item[:article_id])
+ end
+
+ UserInfo.current_user_id = 1
+
+ triggers.each {|trigger|
+ condition = trigger.condition
+
+ # check action
+ if condition['ticket.action']
+ next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != @item[:type]
+ next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == @item[:type]
+ condition.delete('ticket.action')
+ end
+
+ condition['ticket.id'] = {
+ operator: 'is',
+ value: ticket.id,
+ }
+ ticket_count, tickets = Ticket.selectors(condition, 1)
+ next if ticket_count == 0
+ next if tickets.first.id != ticket.id
+
+ # check in min one attribute has changed
+ if @item[:type] == 'update'
+ match = false
+ trigger.condition.each do |key, _value|
+ (object_name, attribute) = key.split('.', 2)
+ next if object_name != 'ticket'
+ next if !@item[:changes][attribute]
+ match = true
+ break
+ end
+ next if !match
+ end
+
+ ticket.perform_changes(trigger.perform, 'trigger')
+ }
+ end
+
+end
diff --git a/app/models/trigger.rb b/app/models/trigger.rb
index 4d5c948a3..63be32c7b 100644
--- a/app/models/trigger.rb
+++ b/app/models/trigger.rb
@@ -1,4 +1,7 @@
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
-class Trigger < ActiveRecord::Base
+class Trigger < ApplicationModel
+ store :condition
+ store :perform
+ validates :name, presence: true
end
diff --git a/db/migrate/20160501000001_update_transaction.rb b/db/migrate/20160501000001_update_transaction.rb
new file mode 100644
index 000000000..c1f6fe4ba
--- /dev/null
+++ b/db/migrate/20160501000001_update_transaction.rb
@@ -0,0 +1,63 @@
+class UpdateTransaction < ActiveRecord::Migration
+ def up
+
+ # return if it's a new setup
+ return if !Setting.find_by(name: 'system_init_done')
+
+ Setting.create_or_update(
+ title: 'Define sync transaction backend.',
+ name: '0100_trigger',
+ area: 'Transaction::Backend::Sync',
+ description: 'Define the transaction backend to execute triggers.',
+ options: {},
+ state: 'Transaction::Trigger',
+ frontend: false
+ )
+ Setting.create_or_update(
+ title: 'Define transaction backend.',
+ name: '0100_notification',
+ area: 'Transaction::Backend::Async',
+ description: 'Define the transaction backend to send agent notifications.',
+ options: {},
+ state: 'Transaction::Notification',
+ frontend: false
+ )
+ Setting.create_or_update(
+ title: 'Define transaction backend.',
+ name: '1000_signature_detection',
+ area: 'Transaction::Backend::Async',
+ description: 'Define the transaction backend to detect customers signature in email.',
+ options: {},
+ state: 'Transaction::SignatureDetection',
+ frontend: false
+ )
+ Setting.create_or_update(
+ title: 'Define transaction backend.',
+ name: '6000_slack_webhook',
+ area: 'Transaction::Backend::Async',
+ description: 'Define the transaction backend which posts messages to (http://www.slack.com).',
+ options: {},
+ state: 'Transaction::Slack',
+ frontend: false
+ )
+ Setting.create_or_update(
+ title: 'Define transaction backend.',
+ name: '9000_clearbit_enrichment',
+ area: 'Transaction::Backend::Async',
+ description: 'Define the transaction backend which will enrich customer and organization informations from (http://www.clearbit.com).',
+ options: {},
+ state: 'Transaction::ClearbitEnrichment',
+ frontend: false
+ )
+ Setting.create_or_update(
+ title: 'Define transaction backend.',
+ name: '9100_cti_caller_id_detection',
+ area: 'Transaction::Backend::Async',
+ description: 'Define the transaction backend which detects caller ids in objects and store them for cti lookups.',
+ options: {},
+ state: 'Transaction::CtiCallerIdDetection',
+ frontend: false
+ )
+
+ end
+end
diff --git a/db/seeds.rb b/db/seeds.rb
index c4b824775..b4a90f59b 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1769,10 +1769,19 @@ Setting.create_if_not_exists(
preferences: { prio: 4 },
frontend: false
)
+Setting.create_if_not_exists(
+ title: 'Define sync transaction backend.',
+ name: '0100_trigger',
+ area: 'Transaction::Backend::Sync',
+ description: 'Define the transaction backend to execute triggers.',
+ options: {},
+ state: 'Transaction::Trigger',
+ frontend: false
+)
Setting.create_if_not_exists(
title: 'Define transaction backend.',
name: '0100_notification',
- area: 'Transaction::Backend',
+ area: 'Transaction::Backend::Async',
description: 'Define the transaction backend to send agent notifications.',
options: {},
state: 'Transaction::Notification',
@@ -1781,7 +1790,7 @@ Setting.create_if_not_exists(
Setting.create_if_not_exists(
title: 'Define transaction backend.',
name: '1000_signature_detection',
- area: 'Transaction::Backend',
+ area: 'Transaction::Backend::Async',
description: 'Define the transaction backend to detect customers signature in email.',
options: {},
state: 'Transaction::SignatureDetection',
@@ -1790,7 +1799,7 @@ Setting.create_if_not_exists(
Setting.create_if_not_exists(
title: 'Define transaction backend.',
name: '6000_slack_webhook',
- area: 'Transaction::Backend',
+ area: 'Transaction::Backend::Async',
description: 'Define the transaction backend which posts messages to (http://www.slack.com).',
options: {},
state: 'Transaction::Slack',
@@ -1900,7 +1909,7 @@ Setting.create_if_not_exists(
Setting.create_if_not_exists(
title: 'Define transaction backend.',
name: '9000_clearbit_enrichment',
- area: 'Transaction::Backend',
+ area: 'Transaction::Backend::Async',
description: 'Define the transaction backend which will enrich customer and organization informations from (http://www.clearbit.com).',
options: {},
state: 'Transaction::ClearbitEnrichment',
@@ -1909,7 +1918,7 @@ Setting.create_if_not_exists(
Setting.create_if_not_exists(
title: 'Define transaction backend.',
name: '9100_cti_caller_id_detection',
- area: 'Transaction::Backend',
+ area: 'Transaction::Backend::Async',
description: 'Define the transaction backend which detects caller ids in objects and store them for cti lookups.',
options: {},
state: 'Transaction::CtiCallerIdDetection',
diff --git a/public/assets/tests/form.js b/public/assets/tests/form.js
index e2c0337f3..8c6e54863 100644
--- a/public/assets/tests/form.js
+++ b/public/assets/tests/form.js
@@ -474,7 +474,6 @@ test("form dependend fields check", function() {
var test_params = {
input1: "",
input2: "some used default",
- input3: undefined,
select1: "false",
select2: "false",
selectmulti2: [ "true", "false" ],
@@ -503,7 +502,6 @@ test("form dependend fields check", function() {
params = App.ControllerForm.params(el)
test_params = {
input1: "",
- input2: undefined,
input3: "some used default",
select1: "true",
select2: "false",
@@ -853,7 +851,6 @@ test("form required_if + shown_if", function() {
input1: "some not used default33",
input2: "some name66",
input3: "some name77",
- input4: undefined,
active: true,
};
params = App.ControllerForm.params(el)
@@ -868,9 +865,6 @@ test("form required_if + shown_if", function() {
el.find('[name="{boolean}active"]').val('false').trigger('change')
test_params = {
input1: "some not used default33",
- input2: undefined,
- input3: undefined,
- input4: undefined,
active: false,
};
params = App.ControllerForm.params(el)
@@ -886,7 +880,6 @@ test("form required_if + shown_if", function() {
input1: "some not used default33",
input2: "some name66",
input3: "some name77",
- input4: undefined,
active: true,
};
params = App.ControllerForm.params(el)
diff --git a/public/assets/tests/form_extended.js b/public/assets/tests/form_extended.js
index 5068daf65..f3ae9aeab 100644
--- a/public/assets/tests/form_extended.js
+++ b/public/assets/tests/form_extended.js
@@ -268,7 +268,7 @@ test('form checks', function() {
model: {
configure_attributes: [
{ name: 'condition', display: 'Conditions', tag: 'ticket_selector', null: true },
- { name: 'executions', display: 'Executions', tag: 'ticket_perform_action', null: true },
+ { name: 'executions', display: 'Executions', tag: 'ticket_perform_action', null: true, notification: true },
]
},
autofocus: true
@@ -290,7 +290,7 @@ test('form checks', function() {
deepEqual(params, test_params, 'form param check');
/* with params or defaults */
- $('#forms').append('
form time check ')
+ $('#forms').append('
form 3 ')
var el = $('#form3')
var defaults = {
condition: {
@@ -342,6 +342,11 @@ test('form checks', function() {
operator: 'remove',
value: 'tag1, tag2',
},
+ 'notification.email': {
+ recipient: 'ticket_customer',
+ subject: 'some subject',
+ body: "some
\nbody",
+ },
},
}
new App.ControllerForm({
@@ -349,7 +354,7 @@ test('form checks', function() {
model: {
configure_attributes: [
{ name: 'condition', display: 'Conditions', tag: 'ticket_selector', null: true },
- { name: 'executions', display: 'Executions', tag: 'ticket_perform_action', null: true },
+ { name: 'executions', display: 'Executions', tag: 'ticket_perform_action', null: true, notification: true },
]
},
params: defaults,
@@ -409,6 +414,11 @@ test('form checks', function() {
operator: 'remove',
value: 'tag1, tag2',
},
+ 'notification.email': {
+ recipient: 'ticket_customer',
+ subject: 'some subject',
+ body: "some
\nbody",
+ },
},
}
deepEqual(params, test_params, 'form param check')
@@ -464,12 +474,172 @@ test('form checks', function() {
operator: 'remove',
value: 'tag1, tag2',
},
+ 'notification.email': {
+ recipient: 'ticket_customer',
+ subject: 'some subject',
+ body: "some
\nbody",
+ },
},
}
deepEqual(params, test_params, 'form param check')
- //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')
+ // change selector
+ el.find('[name="executions::notification.email::subject"]').closest('.js-filterElement').find('.js-remove').click()
+
+ var params = App.ControllerForm.params(el)
+ var test_params = {
+ condition: {
+ 'ticket.title': {
+ operator: 'contains',
+ value: 'some title',
+ },
+ 'ticket.created_at': {
+ operator: 'before (absolute)',
+ value: '2015-09-20T03:41:00.000Z',
+ },
+ 'ticket.updated_at': {
+ operator: 'within last (relative)',
+ range: 'year',
+ value: '2',
+ },
+ 'ticket.organization_id': {
+ operator: 'is not',
+ pre_condition: 'specific',
+ value: '12',
+ },
+ 'ticket.owner_id': {
+ operator: 'is',
+ pre_condition: 'specific',
+ value: '47',
+ value_completion: 'Bob Smith
',
+ },
+ 'ticket.created_by_id': {
+ operator: 'is',
+ pre_condition: 'current_user.id',
+ value: '',
+ value_completion: ''
+ },
+ },
+ executions: {
+ 'ticket.priority_id': {
+ value: '3',
+ },
+ 'ticket.owner_id': {
+ pre_condition: 'specific',
+ value: '47',
+ value_completion: 'Bob Smith '
+ },
+ 'ticket.tags': {
+ operator: 'remove',
+ value: 'tag1, tag2',
+ },
+ },
+ }
+ deepEqual(params, test_params, 'form param check')
+
+ // change selector
+ el.find('.js-attributeSelector').last().find('select').val('notification.email').trigger('change')
+ el.find('[name="executions::notification.email::subject"]').val('some subject')
+ el.find('[data-name="executions::notification.email::body"]').html('lala')
+
+ var params = App.ControllerForm.params(el)
+ var test_params = {
+ condition: {
+ 'ticket.title': {
+ operator: 'contains',
+ value: 'some title',
+ },
+ 'ticket.created_at': {
+ operator: 'before (absolute)',
+ value: '2015-09-20T03:41:00.000Z',
+ },
+ 'ticket.updated_at': {
+ operator: 'within last (relative)',
+ range: 'year',
+ value: '2',
+ },
+ 'ticket.organization_id': {
+ operator: 'is not',
+ pre_condition: 'specific',
+ value: '12',
+ },
+ 'ticket.owner_id': {
+ operator: 'is',
+ pre_condition: 'specific',
+ value: '47',
+ value_completion: 'Bob Smith ',
+ },
+ 'ticket.created_by_id': {
+ operator: 'is',
+ pre_condition: 'current_user.id',
+ value: '',
+ value_completion: ''
+ },
+ },
+ executions: {
+ 'ticket.priority_id': {
+ value: '3',
+ },
+ 'ticket.owner_id': {
+ pre_condition: 'specific',
+ value: '47',
+ value_completion: 'Bob Smith '
+ },
+ 'notification.email': {
+ recipient: 'ticket_owner',
+ subject: 'some subject',
+ body: 'lala',
+ },
+ },
+ }
+ deepEqual(params, test_params, 'form param check')
+
+ /* with params or defaults */
+ $('#forms').append('form 4 ')
+ var el = $('#form4')
+ var defaults = {
+ condition: {
+ 'ticket.title': {
+ operator: 'contains',
+ value: 'some title',
+ },
+ },
+ executions: {
+ 'notification.email': {
+ recipient: 'ticket_customer',
+ subject: 'some subject',
+ body: "some \nbody",
+ },
+ },
+ }
+ new App.ControllerForm({
+ el: el,
+ model: {
+ configure_attributes: [
+ { name: 'condition', display: 'Conditions', tag: 'ticket_selector', null: true },
+ { name: 'executions', display: 'Executions', tag: 'ticket_perform_action', null: true, notification: true },
+ ]
+ },
+ params: defaults,
+ autofocus: true
+ })
+ var params = App.ControllerForm.params(el)
+ var test_params = {
+ condition: {
+ 'ticket.title': {
+ operator: 'contains',
+ value: 'some title',
+ },
+ },
+ executions: {
+
+ 'notification.email': {
+ recipient: 'ticket_customer',
+ subject: 'some subject',
+ body: "some \nbody",
+ },
+ },
+ }
+ deepEqual(params, test_params, 'form param check')
});
\ No newline at end of file
diff --git a/test/fixtures/seeds.rb b/test/fixtures/seeds.rb
index 5ef8d7f9f..c58a66cab 100644
--- a/test/fixtures/seeds.rb
+++ b/test/fixtures/seeds.rb
@@ -1,6 +1,9 @@
# encoding: utf-8
# inital data set as extention to db/seeds.rb
+Trigger.destroy_all
+Job.destroy_all
+
# create email address and apply it to all groups
channel_id = nil
channel = Channel.find_by(area: 'Email::Notification', active: true)
diff --git a/test/unit/ticket_trigger_test.rb b/test/unit/ticket_trigger_test.rb
new file mode 100644
index 000000000..c1e0209eb
--- /dev/null
+++ b/test/unit/ticket_trigger_test.rb
@@ -0,0 +1,337 @@
+# encoding: utf-8
+require 'test_helper'
+
+class TicketTriggerTest < ActiveSupport::TestCase
+ test '1 basic' do
+ trigger1 = Trigger.create_or_update(
+ name: 'auto reply',
+ condition: {
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'new').id.to_s,
+ }
+ },
+ perform: {
+ 'notification.email' => {
+ 'body' => 'some text #{ticket.customer.lastname} #{ticket.title}',
+ 'recipient' => 'ticket_customer',
+ 'subject' => 'Thanks for your inquery (#{ticket.title})!',
+ },
+ 'ticket.priority_id' => {
+ 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
+ },
+ 'ticket.tags' => {
+ 'operator' => 'add',
+ 'value' => 'aa, kk',
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ trigger2 = Trigger.create_or_update(
+ name: 'not matching',
+ condition: {
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'closed').id.to_s,
+ }
+ },
+ perform: {
+ 'ticket.priority_id' => {
+ 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ ticket1 = Ticket.create(
+ title: "some title \n äöüß",
+ group: Group.lookup(name: 'Users'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '2 normal'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ assert(ticket1, 'ticket1 created')
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal([], Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+ article1 = ticket1.articles.last
+ assert_match('Thanks for your inquery (some title äöüß)!', article1.subject)
+ assert_match('Braun some <b>title</b>', article1.body)
+ assert_equal('text/html', article1.content_type)
+
+ ticket1.priority = Ticket::Priority.lookup(name: '2 normal')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+
+ ticket1.state = Ticket::State.lookup(name: 'open')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('open', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+
+ ticket1.state = Ticket::State.lookup(name: 'new')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+
+ ticket2 = Ticket.create(
+ title: "some title\n äöüß",
+ group: Group.lookup(name: 'Users'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'open'),
+ priority: Ticket::Priority.lookup(name: '2 normal'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ assert(ticket2, 'ticket2 created')
+
+ assert_equal('some title äöüß', ticket2.title, 'ticket2.title verify')
+ assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
+ assert_equal('open', ticket2.state.name, 'ticket2.state verify')
+ assert_equal('2 normal', ticket2.priority.name, 'ticket2.priority verify')
+ assert_equal(0, ticket2.articles.count, 'ticket2.articles verify')
+ assert_equal([], Tag.tag_list(object: 'Ticket', o_id: ticket2.id))
+
+ Observer::Transaction.commit
+
+ ticket2 = Ticket.lookup(id: ticket2.id)
+ assert_equal('some title äöüß', ticket2.title, 'ticket2.title verify')
+ assert_equal('Users', ticket2.group.name, 'ticket2.group verify')
+ assert_equal('open', ticket2.state.name, 'ticket2.state verify')
+ assert_equal('2 normal', ticket2.priority.name, 'ticket2.priority verify')
+ assert_equal(0, ticket2.articles.count, 'ticket2.articles verify')
+ assert_equal([], Tag.tag_list(object: 'Ticket', o_id: ticket2.id))
+
+ Trigger.destroy_all
+ end
+
+ test '2 actions - create' do
+ trigger1 = Trigger.create_or_update(
+ name: 'auto reply',
+ condition: {
+ 'ticket.action' => {
+ 'operator' => 'is',
+ 'value' => 'create',
+ },
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'new').id.to_s,
+ }
+ },
+ perform: {
+ 'notification.email' => {
+ 'body' => 'dasdasdasd',
+ 'recipient' => 'ticket_customer',
+ 'subject' => 'asdasdas',
+ },
+ 'ticket.priority_id' => {
+ 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ ticket1 = Ticket.create(
+ title: "some title\n äöüß",
+ group: Group.lookup(name: 'Users'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '2 normal'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ assert(ticket1, 'ticket1 created')
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.priority = Ticket::Priority.lookup(name: '2 normal')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.state = Ticket::State.lookup(name: 'open')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('open', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.state = Ticket::State.lookup(name: 'new')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+
+ Trigger.destroy_all
+ end
+
+ test '2 actions - update' do
+ trigger1 = Trigger.create_or_update(
+ name: 'auto reply',
+ condition: {
+ 'ticket.action' => {
+ 'operator' => 'is',
+ 'value' => 'update',
+ },
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'new').id.to_s,
+ }
+ },
+ perform: {
+ 'notification.email' => {
+ 'body' => 'dasdasdasd',
+ 'recipient' => 'ticket_customer',
+ 'subject' => 'asdasdas',
+ },
+ 'ticket.priority_id' => {
+ 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ ticket1 = Ticket.create(
+ title: "some title\n äöüß",
+ group: Group.lookup(name: 'Users'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '2 normal'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ assert(ticket1, 'ticket1 created')
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.priority = Ticket::Priority.lookup(name: '2 normal')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.state = Ticket::State.lookup(name: 'open')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('open', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(0, ticket1.articles.count, 'ticket1.articles verify')
+
+ ticket1.state = Ticket::State.lookup(name: 'new')
+ ticket1.save
+
+ Observer::Transaction.commit
+
+ ticket1 = Ticket.lookup(id: ticket1.id)
+ assert_equal('some title äöüß', ticket1.title, 'ticket1.title verify')
+ assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
+ assert_equal('new', ticket1.state.name, 'ticket1.state verify')
+ assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
+ assert_equal(1, ticket1.articles.count, 'ticket1.articles verify')
+
+ Trigger.destroy_all
+ end
+
+end