checks_human_changes.rb 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module ChecksHumanChanges
  3. extend ActiveSupport::Concern
  4. def human_changes(record_changes, record, user = nil)
  5. return {} if record_changes.blank?
  6. locale = user.try(:locale) || Setting.get('locale_default') || 'en-us'
  7. attribute_list = allowed_attributes(record.class.name, user)
  8. user_related_changes = user_changes(record_changes, attribute_list)
  9. readable_changes(record, user_related_changes, attribute_list, locale)
  10. end
  11. private
  12. def allowed_attributes(object, user)
  13. ObjectManager::Object.new(object).attributes(user, skip_permission: user.nil?).index_by { |item| item[:name] }
  14. end
  15. def user_changes(record_changes, attribute_list)
  16. user_related_changes = {}
  17. record_changes.each do |key, value|
  18. # If no config exists, use all attributes or if config exists, just use
  19. # existing attributes for user
  20. if attribute_list.blank? || attribute_list[key.to_s]
  21. user_related_changes[key] = value
  22. end
  23. end
  24. user_related_changes
  25. end
  26. def readable_changes(record, user_related_changes, attribute_list, locale)
  27. changes = {}
  28. user_related_changes.each do |key, value|
  29. is_relation_field = key.to_s.end_with?('_id')
  30. attribute_name = attribute_name(is_relation_field, key)
  31. if is_relation_field
  32. value = id_to_relation_value(record, attribute_name, value)
  33. end
  34. attribute = attribute_list&.dig(key.to_s)
  35. display = display_name(attribute) || attribute_name
  36. changes[display] = display_value(locale, value, attribute)
  37. end
  38. changes
  39. end
  40. def attribute_name(is_relation_field, key)
  41. attribute_name = key.to_s
  42. return attribute_name[0..-4] if is_relation_field
  43. attribute_name
  44. end
  45. def id_to_relation_value(record, attribute_name, value)
  46. relation_class = record.public_send(attribute_name)&.class
  47. value.map do |id|
  48. next id if !relation_class
  49. relation_model_visible_value(relation_class, id)
  50. end
  51. end
  52. def relation_model_visible_value(relation_class, id)
  53. relation_model = relation_class.lookup(id: id)
  54. return id.to_s if !relation_model
  55. return relation_model['name'] if relation_model['name']
  56. return relation_model.fullname if relation_model.respond_to?(:fullname)
  57. id
  58. end
  59. def display_name(attribute)
  60. return attribute[:display].to_s if attribute && attribute[:display]
  61. nil
  62. end
  63. def display_value(locale, value, attribute)
  64. if attribute && attribute[:translate]
  65. return [Translation.translate(locale, value[0]), Translation.translate(locale, value[1])]
  66. end
  67. [value[0].to_s, value[1].to_s]
  68. end
  69. end