base.rb 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # Copyright (C) 2012-2024 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. return if !selector[:conditions].nil?
  21. result = {
  22. operator: 'AND',
  23. conditions: [],
  24. }
  25. selector.each_key do |key|
  26. result[:conditions] << {
  27. name: key.to_s,
  28. }.merge(selector[key])
  29. end
  30. @selector = result
  31. end
  32. def set_static_conditions
  33. conditions = static_conditions_ticket + static_conditions_article + static_conditions_merged + static_conditions_ticket_update + static_conditions_user_one
  34. return if conditions.blank?
  35. @selector = {
  36. operator: 'AND',
  37. conditions: conditions + [@selector]
  38. }
  39. end
  40. def static_conditions_ticket
  41. return [] if options[:ticket_id].blank?
  42. [
  43. {
  44. name: 'ticket.id',
  45. operator: 'is',
  46. value: options[:ticket_id]
  47. }
  48. ]
  49. end
  50. def static_conditions_article
  51. return [] if options[:article_id].blank?
  52. [
  53. {
  54. name: 'article.id',
  55. operator: 'is',
  56. value: options[:article_id]
  57. }
  58. ]
  59. end
  60. def static_conditions_merged
  61. return [] if options[:exclude_merged].blank?
  62. [
  63. {
  64. name: 'ticket_state.name',
  65. operator: 'is not',
  66. value: Ticket::StateType.find_by(name: 'merged').states.pluck(:name),
  67. }
  68. ]
  69. end
  70. # https://github.com/zammad/zammad/issues/4550
  71. def static_conditions_ticket_update
  72. return [] if options[:ticket_action] != 'update' || options[:changes_required].blank?
  73. [
  74. {
  75. name: 'ticket.action',
  76. operator: 'is',
  77. value: 'update'
  78. }
  79. ]
  80. end
  81. def static_conditions_user_one
  82. return [] if target_class != User
  83. [
  84. {
  85. name: 'user.id',
  86. operator: 'is not',
  87. value: '1'
  88. }
  89. ]
  90. end
  91. def check_changes
  92. if options[:article_id].present? && attribute_exists?('article.id')
  93. @changed_attributes['article'] = true
  94. end
  95. options[:changes].each_key do |key|
  96. next if !attribute_exists?("ticket.#{key}")
  97. @changed_attributes["ticket.#{key}"] = true
  98. end
  99. end
  100. def attribute_exists?(attribute, check_condition = @selector[:conditions])
  101. result = false
  102. check_condition.each do |condition|
  103. if condition.key?(:conditions)
  104. if attribute_exists?(attribute, condition[:conditions])
  105. result = true
  106. end
  107. elsif condition[:name] == attribute
  108. result = true
  109. end
  110. end
  111. result
  112. end
  113. def get
  114. raise 'NOT_IMPLEMENTED'
  115. end
  116. class InvalidCondition < StandardError
  117. end
  118. end