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



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

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



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

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)


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

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

#cost_price=(price) ⇒ Object



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

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)


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

def deleted?
  deleted_at
end

#gross_profitObject



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

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

#has_default_price?Boolean

Returns:

  • (Boolean)


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

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)


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

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.



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

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

#on_demand=(on_demand) ⇒ Object



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

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)



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

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



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

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



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

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

#options_textObject



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

def options_text
  values = self.option_values.joins(:option_type).order("#{Spree::OptionType.table_name}.position asc")

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

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

#price_in(currency) ⇒ Object



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

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



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
140
# File 'app/models/spree/variant.rb', line 111

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