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



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

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



133
134
135
# File 'app/models/spree/variant.rb', line 133

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

#cost_price=(price) ⇒ Object



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

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)


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

def deleted?
  !!deleted_at
end

#gross_profitObject



73
74
75
# File 'app/models/spree/variant.rb', line 73

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

#has_default_price?Boolean

Returns:

  • (Boolean)


125
126
127
# File 'app/models/spree/variant.rb', line 125

def has_default_price?
  !self.default_price.nil?
end

#in_stock?(quantity = 1) ⇒ Boolean

Returns:

  • (Boolean)


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

def in_stock?(quantity=1)
  Spree::Stock::Quantifier.new(self).can_supply?(quantity)
end

#name_and_skuObject



137
138
139
# File 'app/models/spree/variant.rb', line 137

def name_and_sku
  "#{name} - #{sku}"
end

#on_backorderObject

returns number of units currently on backorder for this variant.



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

def on_backorder
  inventory_units.with_state('backordered').size
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=(options = {}) ⇒ Object



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

def options=(options = {})
  options.each do |option|
    set_option_value(option[:name], option[:value])
  end
end

#options_textObject



63
64
65
66
67
68
69
70
71
# File 'app/models/spree/variant.rb', line 63

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



129
130
131
# File 'app/models/spree/variant.rb', line 129

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

#productObject

Product may be created with deleted_at already set, which would make AR’s default finder return nil. This is a stopgap for that little problem.



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

def product
  Spree::Product.unscoped { super }
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

#should_track_inventory?Boolean

Shortcut method to determine if inventory tracking is enabled for this variant This considers both variant tracking flag and site-wide inventory tracking settings

Returns:

  • (Boolean)


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

def should_track_inventory?
  self.track_inventory? && Spree::Config.track_inventory_levels
end

#total_on_handObject



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

def total_on_hand
  Spree::Stock::Quantifier.new(self).total_on_hand
end