condition.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class CoreWorkflow::Condition
  3. include ::Mixin::HasBackends
  4. attr_accessor :user, :payload, :workflow, :attribute_object, :result_object, :check
  5. def initialize(result_object:, workflow: nil)
  6. @user = result_object.user
  7. @payload = result_object.payload
  8. @workflow = workflow
  9. @attribute_object = result_object.attributes
  10. @result_object = result_object
  11. @check = nil
  12. end
  13. def attributes
  14. @attribute_object.send(@check)
  15. end
  16. def condition_key_value_object(key_split)
  17. case key_split[0]
  18. when 'article'
  19. key_split.shift
  20. obj = @attribute_object.article
  21. when 'session'
  22. key_split.shift
  23. obj = user
  24. when attributes.class.to_s.downcase
  25. key_split.shift
  26. obj = attributes
  27. else
  28. obj = attributes
  29. end
  30. obj
  31. end
  32. def condition_key_value_tags(attribute, obj)
  33. return if !obj.instance_of?(Ticket)
  34. return if attribute != 'tags'
  35. params_tags = payload.dig('params', 'tags')
  36. tags = obj.try(:tag_list)
  37. if @check == 'selected'
  38. tags += if params_tags.is_a?(Array)
  39. params_tags
  40. else
  41. params_tags.to_s.split(', ')
  42. end
  43. end
  44. tags
  45. end
  46. def condition_key_value_group_permissions(attribute, obj)
  47. return if !obj.instance_of?(User)
  48. return if attribute !~ %r{^group_ids_(full|create|change|read|overview)$}
  49. obj.group_ids_access($1)
  50. end
  51. def condition_key_value_obj(attribute, obj)
  52. obj.try(attribute.to_sym)
  53. end
  54. def condition_key_value(key)
  55. return Array(key) if key == 'custom.module'
  56. key_split = key.split('.')
  57. obj = condition_key_value_object(key_split)
  58. key_split.each do |attribute|
  59. obj = condition_key_value_tags(attribute, obj) || condition_key_value_group_permissions(attribute, obj) || condition_key_value_obj(attribute, obj)
  60. end
  61. condition_value_result(obj)
  62. end
  63. def condition_value_result(obj)
  64. Array.wrap(obj).map do |v|
  65. if v.is_a?(Hash)
  66. v['value'].to_s.html2text
  67. else
  68. v.to_s.html2text
  69. end
  70. end
  71. end
  72. def condition_value_match?(key, condition, value)
  73. "CoreWorkflow::Condition::#{condition['operator'].tr(' ()', '_').camelize}".constantize&.new(condition_object: self, result_object: result_object, key: key, condition: condition, value: value)&.match
  74. end
  75. def pre_condition(condition)
  76. pre_condition_current_user(condition)
  77. pre_condition_not_set(condition)
  78. end
  79. def pre_condition_current_user(condition)
  80. return if condition['pre_condition'] != 'current_user.id'
  81. condition['value'] = [user.id.to_s]
  82. end
  83. def pre_condition_not_set(condition)
  84. return if condition['pre_condition'] != 'not_set'
  85. condition['operator'] = 'not_set'
  86. end
  87. def condition_match?(key, condition)
  88. pre_condition(condition)
  89. value_key = condition_key_value(key)
  90. condition_value_match?(key, condition, value_key)
  91. end
  92. def condition_selector_match?(selector)
  93. result = true
  94. selector.each do |key, value|
  95. next if condition_match?(key, value)
  96. result = false
  97. break
  98. end
  99. result
  100. end
  101. def condition_attributes_match?(check)
  102. @check = check
  103. condition = @workflow.send(:"condition_#{@check}")
  104. return true if condition.blank?
  105. condition_selector_match?(condition)
  106. end
  107. def object_match?
  108. return true if @workflow.object.blank?
  109. @workflow.object.include?(@payload['class_name'])
  110. end
  111. def screen_match?
  112. return true if @workflow.preferences['screen'].blank?
  113. Array(@workflow.preferences['screen']).include?(@payload['screen'])
  114. end
  115. def match_all?
  116. return if !object_match?
  117. return if !screen_match?
  118. return if !condition_attributes_match?('saved')
  119. return if !condition_attributes_match?('selected')
  120. true
  121. end
  122. end