class PIM::Item
Add system attributes
Constants
- READ_ONLY_ATTRIBUTES
Public Class Methods
# File pim.rb, line 6256 def self.default_item organization = nil, user = nil, template = nil result = self.new self.all_attributes.each do |a| attribute = data_module.attribute(a) result.instance_variable_set("@#{a}", attribute.default_value) if attribute.default_value end result end
Deprecated: Use “<DATA_MODULE>.item_from_json” instead!
# File pim.rb, line 6252 def self.from_json json, opts = {} PIM.active_module.item_from_json json, opts end
# File pim.rb, line 6265 def initialize opts = {} init_item(opts) if has_option?(:init_multivalue, !data_module.has_option?(:no_init_multivalue)) self.class.all_attributes.each do |a| create_multi_value(a) end end end
Protected Class Methods
# File pim.rb, line 6968 def create_attribute_accessor attribute define_method(to_sym(attribute)) do get_attribute_value(attribute) end define_method("#{attribute}=".to_sym) do |value| set_attribute_value(attribute, value) end end
# File pim.rb, line 6939 def inherited subclass if @class_leaf == true PIM.log_error "Class '#{subclass}' tried to inherit from class '#{self}' which is marked as 'leaf'; '#{subclass}' will not be defined!" return end subclass.initialize_class self end
# File pim.rb, line 6950 def initialize_class parent = nil DataModuleClass.set_data_module self @class_attributes = [] @class_attribute_status = {} @class_hierarchies = [] @model_defined = true if parent @class_parent = parent if parent < PIM::Item if self.to_s.include?(data_module.to_s) data_module.module_categories[self.to_s] = self elsif PIM.is_empty?(self.name) log_trace "Anonymous category class '#{self.to_s}' created but not added to data module '#{data_module.to_s}'" else log_warn "Category class '#{self.to_s}' cannot be added to data module '#{data_module.to_s}'" end end end
Public Instance Methods
# File pim.rb, line 6274 def [] attribute get_attribute_value attribute end
# File pim.rb, line 6278 def []= attribute, value set_attribute_value attribute, value end
# File pim.rb, line 6400 def add_readonly_attribute attribute @readonlyAttributes__ ||= [] attribute = attribute.to_s @readonlyAttributes__ << attribute if !@readonlyAttributes__.include?(attribute) end
# File pim.rb, line 6406 def add_readonly_attributes *attributes attributes.each do |attribute| add_readonly_attribute attribute end end
empty by default
# File pim.rb, line 6429 def after_store old_item = nil, opts = {} [] end
# File pim.rb, line 6367 def as_json opts = {} hash = { "category__" => self.class.to_s } instance_variables.sort.each do |var| key = var.to_s[1..-1] next if hash.include?(key) or (key.start_with?('__') and key.end_with?('__')) value = instance_variable_get(var) if opts[:include_empty] || !value.nil? value = value_as_json(key, value) hash[key] = value if opts[:include_empty] || !value.nil? end end @unknownAttributeValues__.sort_by { |k, v| k }.each do |(k, v)| next if hash.include?(k) or (!opts[:include_empty] && v.nil?) v = PIM::Utils.as_json(v) hash[k.to_s] = v if opts[:include_empty] || !v.nil? end hash end
empty by default
# File pim.rb, line 6424 def before_store old_item, called_from_import [] end
# File pim.rb, line 6394 def calculate_primary_key hash = Hash[instance_variables.map { |name| [name[1..name.size], instance_variable_get(name)] } ] hash[:category__] = self.class.to_s PIM.calculate_primary_key(hash) end
false by default
# File pim.rb, line 6434 def call_after_store? old_item = nil, opts = {} false end
# File pim.rb, line 6329 def copy_item organization copy = self.dup # Set primary key attributes to nil, if any class_primary_key = self.class.class_primary_key if class_primary_key and class_primary_key.attributes class_primary_key.attributes.each do |attribute| variable = "@#{attribute}" if copy.instance_variable_defined?(variable) copy.instance_variable_set(variable, nil) end end end # Set all optional primary key part attributes to nil data_module.all_attributes.each_pair do |key, attribute| next if not attribute.param :potential_primary_key_part variable = "@#{key}" if copy.instance_variable_defined?(variable) copy.instance_variable_set(variable, nil) end end copy end
# File pim.rb, line 6357 def dup duplicate = super duplicate.instance_variables.each do |v| value = duplicate.instance_variable_get(v) value = PIM.dup_value(value) duplicate.instance_variable_set(v, value) end duplicate end
# File pim.rb, line 6388 def from_json hash, opts = {} init_item(opts) @unknownAttributeValues__ = set_instance_values(data_module, self.class, hash) @additionalCategories__.sort!.uniq! if !is_empty?(@additionalCategories__) end
# File pim.rb, line 6282 def get_attribute_value attribute, opts = {} # Returns true, if either this opts or the item's opts have the :create_multivalue option set to 'true' # Defaults to data_model 'no_create_multivalue' flag create_multivalue = PIM::Utils.is_opt?(opts, :create_multivalue, has_option?(:create_multivalue, !data_module.has_option?(:no_create_multivalue))) var = "@#{attribute}" if instance_variable_defined?(var) value = instance_variable_get(var) value = create_multi_value(attribute) if create_multivalue and value.nil? elsif has_attribute?(attribute) value = create_multi_value(attribute) if create_multivalue else value = get_unknown_attribute_value(attribute) end value end
# File pim.rb, line 6322 def has_attribute? attribute attribute = to_sym(attribute) return true if self.class.has_attribute?(attribute) return true if @additionalCategoryAttributes__.include?(attribute) return false end
# File pim.rb, line 6316 def has_attribute_value? attribute var = "@#{attribute}" return instance_variable_defined?("@#{attribute}") end
Checks if item has any changes for specified multi-reference attribute compared to old item
# File pim.rb, line 6598 def has_changed_multi_references? reference_attribute, old_item # Get multi-reference attribute reference_attribute = data_module.attribute(reference_attribute) return false if reference_attribute.nil? return false unless reference_attribute.type_name == 'MultiReference' # Get multi-references new_references = PIM.get_value(self, reference_attribute.name) || [] old_references = PIM.get_value(old_item, reference_attribute.name) || [] # Compare using 'set' return new_references.to_set != old_references.to_set end
empty by default
# File pim.rb, line 6439 def hierarchy_graph hierarchy_name = nil, opts = {} nil end
Method to “revert” a MultiReference attribute value to a list of items to store in before_store.
-
source_reference_attribute => Name of the “source” MultiReference attribute to convert values for
-
target_reference_attribute => Name of the “target” MultiReference reference attribute to convert to (for ‘store_items’)
-
default_action => Name of ‘action’ to add if none is set
Returns ‘nil’ if value could be reverted, e.g. if source or target attribute do not exist or are not defined as expected, or a list of items to store in ‘before_store’.
# File pim.rb, line 6453 def revert_multi_references source_reference_attribute, target_reference_attribute, default_action: nil # Get source attribute source_attribute = data_module.attribute(source_reference_attribute) return nil if source_attribute.nil? return nil unless source_attribute.type_name == 'MultiReference' # Get target attribute, if set target_attribute = data_module.attribute(target_reference_attribute) return nil if target_attribute.nil? return nil unless target_attribute.type_name == 'MultiReference' # Get source multi-reference values source_references = get_attribute_value(source_attribute.name) return nil if PIM.is_empty?(source_references) # Get reference attributes, without mandatory 'primaryKey__' source_value_attribute = source_attribute.param(:value_attribute) return nil if source_value_attribute.nil? source_value_attribute = data_module.attribute(source_value_attribute) return nil if source_value_attribute.nil? reference_attributes = source_value_attribute.sub_attributes - [:primaryKey__, :action__] # Collect items to store by primary key store_items = {} # Add each "reverted" reference source_references.each do |reference| # Only retain references with an 'action__' value action = PIM.get_value(reference, :action__) || default_action next nil if PIM.is_empty?(action) # Ensure a primary key is set reference_primary_key = PIM.get_value(reference, :primaryKey__) next nil if PIM.is_empty?(reference_primary_key) # Never create a "self reference"! next nil if reference_primary_key == self.primaryKey__ # Create map with reference values to set target_reference_values = reference_attributes.map do |reference_attribute| [reference_attribute, PIM.get_value(reference, reference_attribute)] end.to_h # Get or create item store_item = store_items[reference_primary_key] ||= { primaryKey__: reference_primary_key } # Add target reference values store_item[target_reference_attribute] ||= [] store_item[target_reference_attribute] << { primaryKey__: self.primaryKey__, action__: action }.merge(target_reference_values) end return store_items.values end
# File pim.rb, line 6301 def set_attribute_value attribute, value if READ_ONLY_ATTRIBUTES.include?(attribute.to_s) old_value = get_attribute_value(attribute) elsif has_attribute?(attribute) var = "@#{attribute}" old_value = instance_variable_defined?(var) ? instance_variable_get(var) : nil instance_variable_set("@#{attribute}", value) update_additional_category(attribute, old_value, value) else old_value = set_unknown_attribute_value(attribute, value) end old_value end
# File pim.rb, line 6412 def set_readonly_attribute attribute set_readonly_attributes [attribute] end
# File pim.rb, line 6416 def set_readonly_attributes *attributes @readonlyAttributes__ = [] attributes.each do |attribute| add_readonly_attribute attribute end end
Updates a ‘reference’ in a list of references of a MultiReference attribute based on the contained ‘action__’. The uniqueness of a ‘reference’ is defined by the ‘primaryKey__’ value.
See also ‘update_references’!
Returns ‘false’ if no primaryKey or valid action was included, ‘true’ otherwise
# File pim.rb, line 6558 def update_multi_reference references, reference # PrimaryKey of reference primary_key = PIM.get_value(reference, :primaryKey__) return false if PIM.is_empty?(primary_key) primary_key_matcher = lambda { |r| PIM.get_value(r, :primaryKey__) == primary_key } # Get 'existing' reference existing_reference = references.find(&primary_key_matcher) # Create 'new' reference and take out the "action__" new_reference = PIM.as_json(reference) action = new_reference.delete('action__') || new_reference.delete(:action__) # Update references according to action action = action.to_s case action when 'set' # Explicitly set this reference, replacing any existing one references.delete_if(&primary_key_matcher) unless existing_reference.nil? references << new_reference when 'add' # Add, if it does not exist references << new_reference if existing_reference.nil? when 'remove' # Remove if it exists references.delete_if(&primary_key_matcher) unless existing_reference.nil? when 'update' # Update, if it exists unless existing_reference.nil? references.delete_if(&primary_key_matcher) references << new_reference end else return false end return true end
Updates all references for the specified MultiReference attribute based on the contained ‘action__’.
Possible values for ‘action__’ are:
-
set => Explicitly set this reference, replacing any existing one
-
add => Add reference, unless it already exists
-
remove => Remove reference, if it does exist
-
update => Update reference, if it does exist
Returns ‘false’ if specified attribute was invalid or no reference contained a primaryKey or a valid action, ‘true’ otherwise
# File pim.rb, line 6524 def update_multi_references reference_attribute, old_item # Get multi-reference attribute reference_attribute = data_module.attribute(reference_attribute) return false if reference_attribute.nil? return false unless reference_attribute.type_name == 'MultiReference' # Only update, if references contains any 'action__' value new_references = PIM.get_value(self, reference_attribute.name) || [] return false unless new_references.any? { |r| !PIM.get_value(r, :action__).nil? } # Deep copy references update_references = new_references.map(&:dup) # Set new references to deep copy of "old" references old_references = PIM.get_value(old_item, reference_attribute.name) || [] self[reference_attribute.name] = old_references.map(&:dup) # Update new references according to specified "update" references updated = false update_references.each do |reference| updated = update_multi_reference(self[reference_attribute.name], reference) || updated end return updated end