Class: Spree::Variant
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Spree::Variant
- Defined in:
- app/models/spree/variant.rb,
app/models/spree/variant/scopes.rb
Class Method Summary collapse
- .active(currency = nil) ⇒ Object
-
.has_option(option_type, *option_values) ⇒ Object
(also: has_options)
Returns variants that match a given option value.
Instance Method Summary collapse
- #amount_in(currency) ⇒ Object
- #cost_price=(price) ⇒ Object
-
#deleted? ⇒ Boolean
use deleted? rather than checking the attribute directly.
- #gross_profit ⇒ Object
- #has_default_price? ⇒ Boolean
- #in_stock?(quantity = 1) ⇒ Boolean
- #name_and_sku ⇒ Object
-
#on_backorder ⇒ Object
returns number of units currently on backorder for this variant.
- #option_value(opt_name) ⇒ Object
- #options=(options = {}) ⇒ Object
- #options_text ⇒ Object
- #price_in(currency) ⇒ Object
-
#product ⇒ Object
Product may be created with deleted_at already set, which would make AR’s default finder return nil.
- #set_option_value(opt_name, opt_value) ⇒ Object
-
#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.
- #total_on_hand ⇒ Object
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.
80 81 82 |
# File 'app/models/spree/variant.rb', line 80 def deleted? !!deleted_at end |
#gross_profit ⇒ Object
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
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
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_sku ⇒ Object
137 138 139 |
# File 'app/models/spree/variant.rb', line 137 def name_and_sku "#{name} - #{sku}" end |
#on_backorder ⇒ Object
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 ( = {}) .each do |option| set_option_value(option[:name], option[:value]) end end |
#options_text ⇒ Object
63 64 65 66 67 68 69 70 71 |
# File 'app/models/spree/variant.rb', line 63 def 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 |
#product ⇒ Object
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
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_hand ⇒ Object
145 146 147 |
# File 'app/models/spree/variant.rb', line 145 def total_on_hand Spree::Stock::Quantifier.new(self).total_on_hand end |