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
-
.has_option(option_type, *option_values) ⇒ Object
(also: has_options)
Returns variants that match a given option value.
Instance Method Summary collapse
-
#available? ⇒ Boolean
returns true if this variant is allowed to be placed on a new order.
- #cost_price=(price) ⇒ Object
-
#deleted? ⇒ Boolean
use deleted? rather than checking the attribute directly.
- #gross_profit ⇒ Object
-
#in_stock? ⇒ Boolean
(also: #in_stock)
returns true if at least one inventory unit of this variant is “on_hand”.
-
#on_backorder ⇒ Object
returns number of units currently on backorder for this variant.
-
#on_hand ⇒ Object
Returns number of inventory units for this variant (new records haven’t been saved to database, yet).
-
#on_hand=(new_level) ⇒ Object
Adjusts the inventory units to match the given new level.
- #option_value(opt_name) ⇒ Object
- #options_text ⇒ Object
- #price=(price) ⇒ Object
- #set_option_value(opt_name, opt_value) ⇒ Object
Class Method Details
.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
74 75 76 |
# File 'app/models/spree/variant.rb', line 74 def available? Spree::Config[:track_inventory_levels] ? (Spree::Config[:allow_backorders] || in_stock?) : true end |
#cost_price=(price) ⇒ Object
58 59 60 |
# File 'app/models/spree/variant.rb', line 58 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.
95 96 97 |
# File 'app/models/spree/variant.rb', line 95 def deleted? deleted_at end |
#gross_profit ⇒ Object
88 89 90 |
# File 'app/models/spree/variant.rb', line 88 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”
68 69 70 |
# File 'app/models/spree/variant.rb', line 68 def in_stock? Spree::Config[:track_inventory_levels] ? on_hand > 0 : true end |
#on_backorder ⇒ Object
returns number of units currently on backorder for this variant.
63 64 65 |
# File 'app/models/spree/variant.rb', line 63 def on_backorder inventory_units.with_state('backordered').size end |
#on_hand ⇒ Object
Returns number of inventory units for this variant (new records haven’t been saved to database, yet)
31 32 33 |
# File 'app/models/spree/variant.rb', line 31 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.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/models/spree/variant.rb', line 36 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
130 131 132 |
# File 'app/models/spree/variant.rb', line 130 def option_value(opt_name) self.option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation) end |
#options_text ⇒ Object
78 79 80 81 82 83 84 85 86 |
# File 'app/models/spree/variant.rb', line 78 def 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
54 55 56 |
# File 'app/models/spree/variant.rb', line 54 def price=(price) self[:price] = parse_price(price) if price.present? end |
#set_option_value(opt_name, opt_value) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'app/models/spree/variant.rb', line 99 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 |