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

.active(currency = nil) ⇒ Object



43
44
45
# File 'app/models/spree/variant.rb', line 43

def self.active(currency = nil)
  joins(:prices).where(:deleted_at => nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
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

#amount_in(currency) ⇒ Object



160
161
162
# File 'app/models/spree/variant.rb', line 160

def amount_in(currency)
  price_in(currency).try(:amount)
end

#available?Boolean

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

Returns:

  • (Boolean)


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

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

#cost_price=(price) ⇒ Object



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

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)


106
107
108
# File 'app/models/spree/variant.rb', line 106

def deleted?
  deleted_at
end

#gross_profitObject



99
100
101
# File 'app/models/spree/variant.rb', line 99

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

#has_default_price?Boolean

Returns:

  • (Boolean)


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

def has_default_price?
  !self.default_price.nil?
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)


75
76
77
78
79
80
81
# File 'app/models/spree/variant.rb', line 75

def in_stock?
  if Spree::Config[:track_inventory_levels] && !self.on_demand
    on_hand > 0 
  else
    true
  end
end

#on_backorderObject

returns number of units currently on backorder for this variant.



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

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

#on_demand=(on_demand) ⇒ Object



145
146
147
148
149
150
# File 'app/models/spree/variant.rb', line 145

def on_demand=(on_demand)
  self[:on_demand] = on_demand
  if on_demand
    inventory_units.with_state('backordered').each(&:fill_backorder)
  end
end

#on_handObject

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



48
49
50
51
52
53
54
# File 'app/models/spree/variant.rb', line 48

def on_hand
  if Spree::Config[:track_inventory_levels] && !self.on_demand
    count_on_hand 
  else
    (1.0 / 0) # Infinity
  end
end

#on_hand=(new_level) ⇒ Object

set actual attribute



57
58
59
60
61
62
63
# File 'app/models/spree/variant.rb', line 57

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

#option_value(opt_name) ⇒ Object



141
142
143
# File 'app/models/spree/variant.rb', line 141

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

#options_textObject



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

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_in(currency) ⇒ Object



156
157
158
# File 'app/models/spree/variant.rb', line 156

def price_in(currency)
  prices.select{ |price| price.currency == currency }.first || Spree::Price.new(:variant_id => self.id, :currency => currency)
end

#set_option_value(opt_name, opt_value) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'app/models/spree/variant.rb', line 110

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