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

.additional_fieldsObject



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

def self.additional_fields
  ActiveSupport::Deprecation.warn("[SPREE] Spree::Variant.additional_fields will be deprecated in Spree 1.2. Please use Deface and decorators as an alternative to this functionality now.")
  @fields
end

.additional_fields=(new_fields) ⇒ Object



90
91
92
93
94
# File 'app/models/spree/variant.rb', line 90

def self.additional_fields=(new_fields)
  ActiveSupport::Deprecation.warn("[SPREE] Spree::Variant.additional_fields= will be deprecated in Spree 1.2. Please use Deface and decorators as an alternative to this functionality now.")
  attr_accessible *new_fields
  @fields = new_fields
end

.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)


97
98
99
# File 'app/models/spree/variant.rb', line 97

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

#cost_price=(price) ⇒ Object

and cost_price



68
69
70
71
72
# File 'app/models/spree/variant.rb', line 68

def cost_price=(price)
  if price.present?
    self[:cost_price] = price.to_s.gsub(/[^0-9\.-]/, '').to_f
  end
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)


118
119
120
# File 'app/models/spree/variant.rb', line 118

def deleted?
  deleted_at
end

#gross_profitObject



111
112
113
# File 'app/models/spree/variant.rb', line 111

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)


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

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.



75
76
77
# File 'app/models/spree/variant.rb', line 75

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)



37
38
39
# File 'app/models/spree/variant.rb', line 37

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

#on_hand=(new_level) ⇒ Object

Adjusts the inventory units to match the given new level.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/models/spree/variant.rb', line 42

def on_hand=(new_level)
  if Spree::Config[:track_inventory_levels]
    new_level = new_level.to_i

    # increase Inventory when
    if new_level > on_hand
      # fill backordered orders before creating new units
      backordered_units = inventory_units.with_state('backordered')
      backordered_units.slice(0, new_level).each(&:fill_backorder)
      new_level -= backordered_units.length
    end

    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



153
154
155
# File 'app/models/spree/variant.rb', line 153

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

#options_textObject



101
102
103
104
105
106
107
108
109
# File 'app/models/spree/variant.rb', line 101

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

strips all non-price-like characters from the price.



61
62
63
64
65
# File 'app/models/spree/variant.rb', line 61

def price=(price)
  if price.present?
    self[:price] = price.to_s.gsub(/[^0-9\.-]/, '').to_f
  end
end

#set_option_value(opt_name, opt_value) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'app/models/spree/variant.rb', line 122

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

  option_type = Spree::OptionType.find_or_initialize_by_name(opt_name) 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.find_or_initialize_by_option_type_id_and_name(option_type.id, opt_value) do |o|
    o.presentation = opt_value
    o.save!
  end

  self.option_values << option_value
  self.save
end