condition.rb 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # Copyright (C) 2012-2023 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 { |x| x.to_s.html2text }
  65. end
  66. def condition_value_match?(key, condition, value)
  67. "CoreWorkflow::Condition::#{condition['operator'].tr(' ()', '_').camelize}".constantize&.new(condition_object: self, result_object: result_object, key: key, condition: condition, value: value)&.match
  68. end
  69. def pre_condition(condition)
  70. pre_condition_current_user(condition)
  71. pre_condition_not_set(condition)
  72. end
  73. def pre_condition_current_user(condition)
  74. return if condition['pre_condition'] != 'current_user.id'
  75. condition['value'] = [user.id.to_s]
  76. end
  77. def pre_condition_not_set(condition)
  78. return if condition['pre_condition'] != 'not_set'
  79. condition['operator'] = 'not_set'
  80. end
  81. def condition_match?(key, condition)
  82. pre_condition(condition)
  83. value_key = condition_key_value(key)
  84. condition_value_match?(key, condition, value_key)
  85. end
  86. def condition_selector_match?(selector)
  87. result = true
  88. selector.each do |key, value|
  89. next if condition_match?(key, value)
  90. result = false
  91. break
  92. end
  93. result
  94. end
  95. def condition_attributes_match?(check)
  96. @check = check
  97. condition = @workflow.send(:"condition_#{@check}")
  98. return true if condition.blank?
  99. condition_selector_match?(condition)
  100. end
  101. def object_match?
  102. return true if @workflow.object.blank?
  103. @workflow.object.include?(@payload['class_name'])
  104. end
  105. def screen_match?
  106. return true if @workflow.preferences['screen'].blank?
  107. Array(@workflow.preferences['screen']).include?(@payload['screen'])
  108. end
  109. def match_all?
  110. return if !object_match?
  111. return if !screen_match?
  112. return if !condition_attributes_match?('saved')
  113. return if !condition_attributes_match?('selected')
  114. true
  115. end
  116. end