Class: Spree::Variant

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/spree/variant.rb,
app/models/spree/variant/scopes.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.has_option(option_type, *option_values) ⇒ Object Also known as: has_options

Returns variants that match a given option value

Example:

product.variants_including_master.has_option(OptionType.find_by_name(“shoe-size”),OptionValue.find_by_name(“8”))



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'app/models/spree/variant/scopes.rb', line 12

def has_option(option_type, *option_values)
  option_types = OptionType.table_name

  option_type_conditions = case option_type
  when OptionType then { "#{option_types}.name" => option_type.name }
  when String     then { "#{option_types}.name" => option_type }
  else                 { "#{option_types}.id"   => option_type }
  end

  relation = joins(:option_values => :option_type).where(option_type_conditions)

  option_values_conditions = option_values.each do |option_value|
    option_value_conditions = case option_value
    when OptionValue then { "#{OptionValue.table_name}.name" => option_value.name }
    when String      then { "#{OptionValue.table_name}.name" => option_value }
    else                  { "#{OptionValue.table_name}.id"   => option_value }
    end
    relation = relation.where(option_value_conditions)
  end

  relation
end

Instance Method Details

#available?Boolean

returns true if this variant is allowed to be placed on a new order

Returns:

  • (Boolean)


65
66
67
# File 'app/models/spree/variant.rb', line 65

def available?
  Spree::Config[:track_inventory_levels] ? (Spree::Config[:allow_backorders] || in_stock?) : true
end

#cost_price=(price) ⇒ Object



49
50
51
# File 'app/models/spree/variant.rb', line 49

def cost_price=(price)
  self[:cost_price] = parse_price(price) if price.present?
end

#deleted?Boolean

use deleted? rather than checking the attribute directly. this allows extensions to override deleted? if they want to provide their own definition.

Returns:

  • (Boolean)


86
87
88
# File 'app/models/spree/variant.rb', line 86

def deleted?
  deleted_at
end

#gross_profitObject



79
80
81
# File 'app/models/spree/variant.rb', line 79

def gross_profit
  cost_price.nil? ? 0 : (price - cost_price)
end

#in_stock?Boolean Also known as: in_stock

returns true if at least one inventory unit of this variant is “on_hand”

Returns:

  • (Boolean)


59
60
61
# File 'app/models/spree/variant.rb', line 59

def in_stock?
  Spree::Config[:track_inventory_levels] ? on_hand > 0 : true
end

#on_backorderObject

returns number of units currently on backorder for this variant.



54
55
56
# File 'app/models/spree/variant.rb', line 54

def on_backorder
  inventory_units.with_state('backordered').size
end

#on_handObject

Returns number of inventory units for this variant (new records haven’t been saved to database, yet)



32
33
34
# File 'app/models/spree/variant.rb', line 32

def on_hand
  Spree::Config[:track_inventory_levels] ? count_on_hand : (1.0 / 0) # Infinity
end

#on_hand=(new_level) ⇒ Object

set actual attribute



37
38
39
40
41
42
43
# File 'app/models/spree/variant.rb', line 37

def on_hand=(new_level)
  if Spree::Config[:track_inventory_levels]
    self.count_on_hand = new_level
  else
    raise 'Cannot set on_hand value when Spree::Config[:track_inventory_levels] is false'
  end
end

#option_value(opt_name) ⇒ Object



121
122
123
# File 'app/models/spree/variant.rb', line 121

def option_value(opt_name)
  self.option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
end

#options_textObject



69
70
71
72
73
74
75
76
77
# File 'app/models/spree/variant.rb', line 69

def options_text
  values = self.option_values.sort_by(&:position)

  values.map! do |ov|
    "#{ov.option_type.presentation}: #{ov.presentation}"
  end

  values.to_sentence({ :words_connector => ", ", :two_words_connector => ", " })
end

#price=(price) ⇒ Object



45
46
47
# File 'app/models/spree/variant.rb', line 45

def price=(price)
  self[:price] = parse_price(price) if price.present?
end

#set_option_value(opt_name, opt_value) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'app/models/spree/variant.rb', line 90

def set_option_value(opt_name, opt_value)
  # no option values on master
  return if self.is_master

  option_type = Spree::OptionType.where(:name => opt_name).first_or_initialize do |o|
    o.presentation = opt_name
    o.save!
  end

  current_value = self.option_values.detect { |o| o.option_type.name == opt_name }

  unless current_value.nil?
    return if current_value.name == opt_value
    self.option_values.delete(current_value)
  else
    # then we have to check to make sure that the product has the option type
    unless self.product.option_types.include? option_type
      self.product.option_types << option_type
      self.product.save
    end
  end

  option_value = Spree::OptionValue.where(:option_type_id => option_type.id, :name => opt_value).first_or_initialize do |o|
    o.presentation = opt_value
    o.save!
  end

  self.option_values << option_value
  self.save
end