Module: Models::Kittable

Extended by:
ActiveSupport::Concern
Includes:
Memery
Included in:
Item
Defined in:
app/concerns/models/kittable.rb

Has many collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.kitsActiveRecord::Relation<Models::Kittable>

A relation of Models::Kittables that are kits. Active Record Scope

Returns:

See Also:



17
# File 'app/concerns/models/kittable.rb', line 17

scope :kits, -> { where(is_kit: true) }

.non_kitsActiveRecord::Relation<Models::Kittable>

A relation of Models::Kittables that are non kits. Active Record Scope

Returns:

See Also:



18
# File 'app/concerns/models/kittable.rb', line 18

scope :non_kits, -> { where(is_kit: false) }

Instance Method Details

#box_contentsObject



60
61
62
# File 'app/concerns/models/kittable.rb', line 60

def box_contents
  3.times.map { |i| kit_target_item_relations.collect { |ir| ir.box_quantities[i] > 0 ? "#{ir.box_quantities[i]} x #{ir.target_item.sku}" : nil }.compact.to_sentence(last_word_connector: ' and ') }
end

#consolidate_linked_kitsObject



44
45
46
# File 'app/concerns/models/kittable.rb', line 44

def consolidate_linked_kits
  kit_parents.each { |kp| Item::KitConsolidator.new(kp).consolidate_weights_and_dimensions.commit }
end

#get_kit_item_idsObject



111
112
113
# File 'app/concerns/models/kittable.rb', line 111

def get_kit_item_ids
  get_kit_items.pluck(:id)
end

#get_kit_items(spec_only: nil) ⇒ Object



101
102
103
104
105
# File 'app/concerns/models/kittable.rb', line 101

def get_kit_items(spec_only: nil)
  return Item.none unless is_kit?

  spec_only ? kit_components_for_specs : kit_components
end

#get_multi_box_item_contents_item_id_hash_arrayObject



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'app/concerns/models/kittable.rb', line 64

def get_multi_box_item_contents_item_id_hash_array
  contents_item_id_hash_array = []
  boxes.each_with_index do |_box, i|
    contents_hash = {}
    kit_target_item_relations.each do |ir|
      item_id = ir.target_item.id.to_s
      if ir.box_quantities[i] > 0
        contents_hash[item_id] ||= 0
        contents_hash[item_id] += ir.box_quantities[i]
      end
    end
    contents_item_id_hash_array << contents_hash
  end
  contents_item_id_hash_array
end

#get_self_and_kit_item_idsObject



107
108
109
# File 'app/concerns/models/kittable.rb', line 107

def get_self_and_kit_item_ids
  get_self_and_kit_items.map(&:id)
end

#get_self_and_kit_items(spec_only: nil) ⇒ Array<Item>

Pulls the item and its kit components. If you specify spec only then only those target items marked include_in_spec will be pulled
This allows greater control of how specs are rendered

Always returns an Array. For non-kit items, returns [self] without a DB query.
For kit items, returns self + kit components ordered by category priority then SKU.
Result is memoized per spec_only variant to avoid N+1 queries when called repeatedly
(e.g. once per ProductSpecification in Item::SpecificationsMasher).

Parameters:

  • spec_only (Boolean, nil) (defaults to: nil)

    If true, only includes kit components marked for spec display

Returns:

  • (Array<Item>)

    Self and kit components (if any)



90
91
92
93
94
95
96
97
98
# File 'app/concerns/models/kittable.rb', line 90

def get_self_and_kit_items(spec_only: nil)
  if is_kit?
    item_ids = [id]
    item_ids += spec_only ? kit_components_for_spec_ids : kit_component_ids
    Item.where(id: item_ids).joins(:product_category).order(Item[:id].not_eq(id), ProductCategory[:priority], Item[:sku]).to_a
  else
    [self]
  end
end

#is_part_of_a_kit?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'app/concerns/models/kittable.rb', line 28

def is_part_of_a_kit?
  kit_parents.present?
end

#is_part_of_an_active_kit?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'app/concerns/models/kittable.rb', line 32

def is_part_of_an_active_kit?
  kit_parents.active.present?
end

#kit_componentsActiveRecord::Relation<KitComponent>

Returns:

  • (ActiveRecord::Relation<KitComponent>)

See Also:



12
# File 'app/concerns/models/kittable.rb', line 12

has_many :kit_components, through: :kit_target_item_relations, source: :target_item

#kit_components_for_specsActiveRecord::Relation<KitComponentsForSpec>

Returns:

  • (ActiveRecord::Relation<KitComponentsForSpec>)

See Also:



13
# File 'app/concerns/models/kittable.rb', line 13

has_many :kit_components_for_specs, through: :kit_target_item_relations_for_specs, source: :target_item

#kit_contents(short = false, with_brackets = false) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# File 'app/concerns/models/kittable.rb', line 48

def kit_contents(short = false, with_brackets = false)
  contents = nil
  if kit_target_item_relations.any?
    contents = ''
    contents += "The #{sku} is " unless short
    contents += 'composed of '
    contents += kit_target_item_relations.collect { |ir| "#{ir.quantity} x #{ir.target_item.sku}" }.to_sentence(last_word_connector: ' and ')
    contents = "(#{contents})" if with_brackets
  end
  contents
end

#kit_parentsActiveRecord::Relation<KitParent>

Returns:

  • (ActiveRecord::Relation<KitParent>)

See Also:



15
# File 'app/concerns/models/kittable.rb', line 15

has_many :kit_parents, through: :kit_source_item_relations, source: :source_item

#kit_source_item_relationsActiveRecord::Relation<ItemRelation>

Returns:

See Also:



14
# File 'app/concerns/models/kittable.rb', line 14

has_many :kit_source_item_relations, -> { kit_components }, class_name: 'ItemRelation', foreign_key: 'target_item_id', inverse_of: :target_item, dependent: :destroy

#kit_target_item_relationsActiveRecord::Relation<ItemRelation>

Returns:

See Also:



10
# File 'app/concerns/models/kittable.rb', line 10

has_many :kit_target_item_relations, -> { kit_components }, class_name: 'ItemRelation', foreign_key: 'source_item_id', inverse_of: :source_item, dependent: :destroy

#kit_target_item_relations_for_specsActiveRecord::Relation<ItemRelation>

Returns:

See Also:



11
# File 'app/concerns/models/kittable.rb', line 11

has_many :kit_target_item_relations_for_specs, -> { kit_components_for_specs }, class_name: 'ItemRelation', foreign_key: 'source_item_id', inverse_of: :source_item, dependent: :destroy

#shipping_dimensions_changed?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'app/concerns/models/kittable.rb', line 36

def shipping_dimensions_changed?
  base_weight_changed? or shipping_weight_changed? or shipping_length_changed? or shipping_width_changed? or shipping_height_changed?
end

#store_item_for(store_id, location) ⇒ Object



40
41
42
# File 'app/concerns/models/kittable.rb', line 40

def store_item_for(store_id, location)
  store_items.where(store_id:, location:).first_or_create(qty_available: 0, is_discontinued: false, unit_cogs: 0, qty_committed: 0)
end