app/models/core_workflow/condition.rb
# Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
class CoreWorkflow::Condition
include ::Mixin::HasBackends
attr_accessor :user, :payload, :workflow, :attribute_object, :result_object, :check
def initialize(result_object:, workflow: nil)
@user = result_object.user
@payload = result_object.payload
@workflow = workflow
@attribute_object = result_object.attributes
@result_object = result_object
@check = nil
end
def attributes
@attribute_object.send(@check)
end
def condition_key_value_object(key_split)
case key_split[0]
when 'article'
key_split.shift
obj = @attribute_object.article
when 'session'
key_split.shift
obj = user
when attributes.class.to_s.downcase
key_split.shift
obj = attributes
else
obj = attributes
end
obj
end
def condition_key_value_tags(attribute, obj)
return if !obj.instance_of?(Ticket)
return if attribute != 'tags'
params_tags = payload.dig('params', 'tags')
tags = obj.try(:tag_list)
if @check == 'selected'
tags += if params_tags.is_a?(Array)
params_tags
else
params_tags.to_s.split(', ')
end
end
tags
end
def condition_key_value_group_permissions(attribute, obj)
return if !obj.instance_of?(User)
return if attribute !~ %r{^group_ids_(full|create|change|read|overview)$}
obj.group_ids_access($1)
end
def condition_key_value_obj(attribute, obj)
obj.try(attribute.to_sym)
end
def condition_key_value(key)
return Array(key) if key == 'custom.module'
key_split = key.split('.')
obj = condition_key_value_object(key_split)
key_split.each do |attribute|
obj = condition_key_value_tags(attribute, obj) || condition_key_value_group_permissions(attribute, obj) || condition_key_value_obj(attribute, obj)
end
condition_value_result(obj)
end
def condition_value_result(obj)
Array.wrap(obj).map do |v|
if v.is_a?(Hash)
v['value'].to_s.html2text
else
v.to_s.html2text
end
end
end
def condition_value_match?(key, condition, value)
"CoreWorkflow::Condition::#{condition['operator'].tr(' ()', '_').camelize}".constantize&.new(condition_object: self, result_object: result_object, key: key, condition: condition, value: value)&.match
end
def pre_condition(condition)
pre_condition_current_user(condition)
pre_condition_not_set(condition)
end
def pre_condition_current_user(condition)
return if condition['pre_condition'] != 'current_user.id'
condition['value'] = [user.id.to_s]
end
def pre_condition_not_set(condition)
return if condition['pre_condition'] != 'not_set'
condition['operator'] = 'not_set'
end
def condition_match?(key, condition)
pre_condition(condition)
value_key = condition_key_value(key)
condition_value_match?(key, condition, value_key)
end
def condition_selector_match?(selector)
result = true
selector.each do |key, value|
next if condition_match?(key, value)
result = false
break
end
result
end
def condition_attributes_match?(check)
@check = check
condition = @workflow.send(:"condition_#{@check}")
return true if condition.blank?
condition_selector_match?(condition)
end
def object_match?
return true if @workflow.object.blank?
@workflow.object.include?(@payload['class_name'])
end
def screen_match?
return true if @workflow.preferences['screen'].blank?
Array(@workflow.preferences['screen']).include?(@payload['screen'])
end
def match_all?
return if !object_match?
return if !screen_match?
return if !condition_attributes_match?('saved')
return if !condition_attributes_match?('selected')
true
end
end