trigger.rb 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
  2. class Transaction::Trigger
  3. =begin
  4. {
  5. object: 'Ticket',
  6. type: 'update',
  7. object_id: 123,
  8. interface_handle: 'application_server', # application_server|websocket|scheduler
  9. changes: {
  10. 'attribute1' => [before, now],
  11. 'attribute2' => [before, now],
  12. },
  13. created_at: Time.zone.now,
  14. user_id: 123,
  15. },
  16. =end
  17. def initialize(item, params = {})
  18. @item = item
  19. @params = params
  20. end
  21. def perform
  22. # return if we run import mode
  23. return if Setting.get('import_mode')
  24. return if @item[:object] != 'Ticket'
  25. triggers = if Rails.configuration.db_case_sensitive
  26. Trigger.where(active: true).order('LOWER(name)')
  27. else
  28. Trigger.where(active: true).order(:name)
  29. end
  30. return if triggers.empty?
  31. ticket = Ticket.lookup(id: @item[:object_id])
  32. return if !ticket
  33. if @item[:article_id]
  34. article = Ticket::Article.lookup(id: @item[:article_id])
  35. end
  36. original_user_id = UserInfo.current_user_id
  37. Transaction.execute(reset_user_id: true, disable: ['Transaction::Trigger', 'Transaction::Notification']) do
  38. triggers.each { |trigger|
  39. condition = trigger.condition
  40. # check if one article attribute is used
  41. one_has_changed_done = false
  42. article_selector = false
  43. trigger.condition.each do |key, _value|
  44. (object_name, attribute) = key.split('.', 2)
  45. next if object_name != 'article'
  46. next if attribute == 'id'
  47. article_selector = true
  48. end
  49. if article && article_selector
  50. one_has_changed_done = true
  51. end
  52. if article && @item[:type] == 'update'
  53. one_has_changed_done = true
  54. end
  55. # check ticket "has changed" options
  56. has_changed_done = true
  57. condition.each do |key, value|
  58. next if !value
  59. next if !value['operator']
  60. next if !value['operator']['has changed']
  61. # remove condition item, because it has changed
  62. (object_name, attribute) = key.split('.', 2)
  63. next if object_name != 'ticket'
  64. next if !@item[:changes]
  65. next if !@item[:changes].key?(attribute)
  66. condition.delete(key)
  67. one_has_changed_done = true
  68. end
  69. # check if we have not matching "has changed" attributes
  70. condition.each do |_key, value|
  71. next if !value
  72. next if !value['operator']
  73. next if !value['operator']['has changed']
  74. has_changed_done = false
  75. break
  76. end
  77. # check ticket action
  78. if condition['ticket.action']
  79. next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != @item[:type]
  80. next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == @item[:type]
  81. condition.delete('ticket.action')
  82. end
  83. next if !has_changed_done
  84. # check in min one attribute of condition has changed on update
  85. one_has_changed_condition = false
  86. if @item[:type] == 'update'
  87. # verify if ticket condition exists
  88. condition.each do |key, _value|
  89. (object_name, attribute) = key.split('.', 2)
  90. next if object_name != 'ticket'
  91. one_has_changed_condition = true
  92. next if !@item[:changes] || !@item[:changes].key?(attribute)
  93. one_has_changed_done = true
  94. break
  95. end
  96. next if one_has_changed_condition && !one_has_changed_done
  97. end
  98. # check if ticket selector is matching
  99. condition['ticket.id'] = {
  100. operator: 'is',
  101. value: ticket.id,
  102. }
  103. next if article_selector && !article
  104. # check if article selector is matching
  105. if article_selector
  106. condition['article.id'] = {
  107. operator: 'is',
  108. value: article.id,
  109. }
  110. end
  111. # verify is condition is matching
  112. ticket_count, tickets = Ticket.selectors(condition, 1)
  113. next if ticket_count.zero?
  114. next if tickets.first.id != ticket.id
  115. user_id = ticket.updated_by_id
  116. if article
  117. user_id = article.updated_by_id
  118. end
  119. ticket.perform_changes(trigger.perform, 'trigger', @item, user_id)
  120. }
  121. end
  122. UserInfo.current_user_id = original_user_id
  123. end
  124. end