class PIM::Item

Add system attributes

Constants

READ_ONLY_ATTRIBUTES

Public Class Methods

default_item(organization = nil, user = nil, template = nil) click to toggle source
# 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
from_json(json, opts = {}) click to toggle source

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
new(opts = {}) click to toggle source
# 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

create_attribute_accessor(attribute) click to toggle source
# 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
inherited(subclass) click to toggle source
# 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
initialize_class(parent = nil) click to toggle source
# 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

[](attribute) click to toggle source
# File pim.rb, line 6274
def [] attribute
  get_attribute_value attribute
end
[]=(attribute, value) click to toggle source
# File pim.rb, line 6278
def []= attribute, value
  set_attribute_value attribute, value
end
add_readonly_attribute(attribute) click to toggle source
# File pim.rb, line 6400
def add_readonly_attribute attribute
  @readonlyAttributes__ ||= []
  attribute = attribute.to_s
  @readonlyAttributes__ << attribute if !@readonlyAttributes__.include?(attribute)
end
add_readonly_attributes(*attributes) click to toggle source
# File pim.rb, line 6406
def add_readonly_attributes *attributes
  attributes.each do |attribute|
    add_readonly_attribute attribute
  end
end
after_store(old_item = nil, opts = {}) click to toggle source

empty by default

# File pim.rb, line 6429
def after_store old_item = nil, opts = {}
  []
end
as_json(opts = {}) click to toggle source
# 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
before_store(old_item, called_from_import) click to toggle source

empty by default

# File pim.rb, line 6424
def before_store old_item, called_from_import
  []
end
calculate_primary_key() click to toggle source
# 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
call_after_store?(old_item = nil, opts = {}) click to toggle source

false by default

# File pim.rb, line 6434
def call_after_store? old_item = nil, opts = {}
  false
end
copy_item(organization) click to toggle source
# 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
dup() click to toggle source
Calls superclass method
# 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
from_json(hash, opts = {}) click to toggle source
# 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
get(attribute, opts = {})
Alias for: get_attribute_value
get_attribute_value(attribute, opts = {}) click to toggle source
# 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
Also aliased as: get
has?(attribute)
has_attribute?(attribute) click to toggle source
# 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
has_attribute_value?(attribute) click to toggle source
# File pim.rb, line 6316
def has_attribute_value? attribute
  var = "@#{attribute}"
  return instance_variable_defined?("@#{attribute}")
end
Also aliased as: has?
has_changed_multi_references?(reference_attribute, old_item) click to toggle source

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
hierarchy_graph(hierarchy_name = nil, opts = {}) click to toggle source

empty by default

# File pim.rb, line 6439
def hierarchy_graph hierarchy_name = nil, opts = {}
  nil
end
revert_multi_references(source_reference_attribute, target_reference_attribute, default_action: nil) click to toggle source

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
set(attribute, value)
Alias for: set_attribute_value
set_attribute_value(attribute, value) click to toggle source
# 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
Also aliased as: set
set_readonly_attribute(attribute) click to toggle source
# File pim.rb, line 6412
def set_readonly_attribute attribute
  set_readonly_attributes [attribute]
end
set_readonly_attributes(*attributes) click to toggle source
# File pim.rb, line 6416
def set_readonly_attributes *attributes
  @readonlyAttributes__ = []
  attributes.each do |attribute|
    add_readonly_attribute attribute
  end
end
update_multi_reference(references, reference) click to toggle source

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
update_multi_references(reference_attribute, old_item) click to toggle source

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