base.rb 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. class Selector::Base
  3. attr_accessor :selector, :options, :changed_attributes, :target_class, :target_table, :target_name
  4. def initialize(selector:, options:, target_class: Ticket)
  5. if selector.respond_to?(:permit!)
  6. selector = selector.permit!.to_h
  7. end
  8. @selector = Marshal.load(Marshal.dump(selector)).deep_symbolize_keys
  9. @options = options
  10. @target_class = target_class
  11. @target_table = target_class.table_name
  12. @target_name = target_table.delete_suffix('s')
  13. @changed_attributes = {}
  14. @options[:changes] ||= {}
  15. migrate
  16. set_static_conditions
  17. check_changes
  18. end
  19. def migrate
  20. @selector = self.class.migrate_selector(selector)
  21. end
  22. def self.migrate_selector(value)
  23. return value if !value[:conditions].nil?
  24. result = {
  25. operator: 'AND',
  26. conditions: [],
  27. }
  28. value.each_key do |key|
  29. result[:conditions] << {
  30. name: key.to_s,
  31. }.merge(value[key])
  32. end
  33. result
  34. end
  35. def set_static_conditions
  36. conditions = static_conditions_ticket + static_conditions_article + static_conditions_merged + static_conditions_ticket_update + static_conditions_user_one
  37. return if conditions.blank?
  38. @selector = {
  39. operator: 'AND',
  40. conditions: conditions + [@selector]
  41. }
  42. end
  43. def static_conditions_ticket
  44. return [] if options[:ticket_id].blank?
  45. [
  46. {
  47. name: 'ticket.id',
  48. operator: 'is',
  49. value: options[:ticket_id]
  50. }
  51. ]
  52. end
  53. def static_conditions_article
  54. return [] if options[:article_id].blank?
  55. [
  56. {
  57. name: 'article.id',
  58. operator: 'is',
  59. value: options[:article_id]
  60. }
  61. ]
  62. end
  63. def static_conditions_merged
  64. return [] if options[:exclude_merged].blank?
  65. [
  66. {
  67. name: 'ticket_state.name',
  68. operator: 'is not',
  69. value: Ticket::StateType.find_by(name: 'merged').states.pluck(:name),
  70. }
  71. ]
  72. end
  73. # https://github.com/zammad/zammad/issues/4550
  74. def static_conditions_ticket_update
  75. return [] if options[:ticket_action] != 'update' || options[:changes_required].blank?
  76. [
  77. {
  78. name: 'ticket.action',
  79. operator: 'is',
  80. value: 'update'
  81. }
  82. ]
  83. end
  84. def static_conditions_user_one
  85. return [] if target_class != User
  86. [
  87. {
  88. name: 'user.id',
  89. operator: 'is not',
  90. value: '1'
  91. }
  92. ]
  93. end
  94. def check_changes
  95. if options[:article_id].present? && attribute_exists?('article.id')
  96. @changed_attributes['article'] = true
  97. end
  98. options[:changes].each_key do |key|
  99. next if !attribute_exists?("ticket.#{key}")
  100. @changed_attributes["ticket.#{key}"] = true
  101. end
  102. end
  103. def attribute_exists?(attribute, check_condition = @selector[:conditions])
  104. result = false
  105. check_condition.each do |condition|
  106. if condition.key?(:conditions)
  107. if attribute_exists?(attribute, condition[:conditions])
  108. result = true
  109. end
  110. elsif condition[:name] == attribute
  111. result = true
  112. end
  113. end
  114. result
  115. end
  116. def get
  117. raise 'NOT_IMPLEMENTED'
  118. end
  119. class InvalidCondition < StandardError
  120. end
  121. end