Class: Spree::Product
Instance Attribute Summary collapse
-
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
-
#prototype_id ⇒ Object
Adding properties and option types on creation based on a chosen prototype.
Class Method Summary collapse
Instance Method Summary collapse
-
#available? ⇒ Boolean
determine if product is available.
-
#backorderable? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259.
-
#backordered? ⇒ Boolean
determine if any variant (including master) is out of stock and backorderable.
- #brand ⇒ Object
-
#can_supply? ⇒ Boolean
determine if any variant (including master) can be supplied.
-
#categorise_variants_from_option(opt_type) ⇒ Object
split variants list into hash which shows mapping of opt value onto matching variants eg categorise_variants_from_option(color) => -> […], “blue” -> […].
- #category ⇒ Object
-
#default_variant ⇒ Spree::Variant
Returns default Variant for Product If ‘track_inventory_levels` is enabled it will try to find the first Variant in stock or backorderable, if there’s none it will return first Variant sorted by ‘position` attribute If `track_inventory_levels` is disabled it will return first Variant sorted by `position` attribute.
-
#default_variant_id ⇒ Integer
Returns default Variant ID for Product.
-
#deleted? ⇒ Boolean
use deleted? rather than checking the attribute directly.
- #discontinue! ⇒ Object
- #discontinued? ⇒ Boolean
-
#duplicate ⇒ Object
for adding products which are closely related to existing ones define “duplicate_extra” for site-specific actions, eg for additional fields.
- #empty_option_values? ⇒ Boolean
-
#ensure_option_types_exist_for_values_hash ⇒ Object
Ensures option_types and product_option_types exist for keys in option_values_hash.
- #find_or_build_master ⇒ Object
-
#has_variants? ⇒ Boolean
the master variant is not a member of the variants array.
-
#in_stock? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259.
-
#master ⇒ Object
Master variant may be deleted (i.e. when the product is deleted) which would make AR’s default finder return nil.
- #property(property_name) ⇒ Object
-
#purchasable? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259.
- #set_property(property_name, property_value, property_presentation = property_name) ⇒ Object
- #tax_category ⇒ Object
- #total_on_hand ⇒ Object
-
#variants_and_option_values(current_currency = nil) ⇒ Object
Suitable for displaying only variants that has at least one option value.
Methods inherited from Base
belongs_to_required_by_default, page, spree_base_scopes
Methods included from Spree::Preferences::Preferable
#clear_preferences, #default_preferences, #defined_preferences, #get_preference, #has_preference!, #has_preference?, #preference_default, #preference_type, #set_preference
Instance Attribute Details
#option_values_hash ⇒ Object
Returns the value of attribute option_values_hash.
108 109 110 |
# File 'app/models/spree/product.rb', line 108 def option_values_hash @option_values_hash end |
#prototype_id ⇒ Object
Adding properties and option types on creation based on a chosen prototype
185 186 187 |
# File 'app/models/spree/product.rb', line 185 def prototype_id @prototype_id end |
Class Method Details
.like_any(fields, values) ⇒ Object
248 249 250 251 252 253 |
# File 'app/models/spree/product.rb', line 248 def self.like_any(fields, values) conditions = fields.product(values).map do |(field, value)| arel_table[field].matches("%#{value}%") end where conditions.inject(:or) end |
Instance Method Details
#available? ⇒ Boolean
determine if product is available. deleted products and products with nil or future available_on date are not available
218 219 220 |
# File 'app/models/spree/product.rb', line 218 def available? !(available_on.nil? || available_on.future?) && !deleted? && !discontinued? end |
#backorderable? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259
141 142 143 |
# File 'app/models/spree/product.rb', line 141 def backorderable? variants_including_master.any?(&:backorderable?) end |
#backordered? ⇒ Boolean
determine if any variant (including master) is out of stock and backorderable
236 237 238 |
# File 'app/models/spree/product.rb', line 236 def backordered? variants_including_master.any?(&:backordered?) end |
#brand ⇒ Object
299 300 301 |
# File 'app/models/spree/product.rb', line 299 def brand taxons.joins(:taxonomy).find_by(spree_taxonomies: { name: Spree.t(:taxonomy_brands_name) }) end |
#can_supply? ⇒ Boolean
determine if any variant (including master) can be supplied
231 232 233 |
# File 'app/models/spree/product.rb', line 231 def can_supply? variants_including_master.any?(&:can_supply?) end |
#categorise_variants_from_option(opt_type) ⇒ Object
split variants list into hash which shows mapping of opt value onto matching variants eg categorise_variants_from_option(color) => -> […], “blue” -> […]
242 243 244 245 246 |
# File 'app/models/spree/product.rb', line 242 def categorise_variants_from_option(opt_type) return {} unless option_types.include?(opt_type) variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } } end |
#category ⇒ Object
303 304 305 306 307 308 |
# File 'app/models/spree/product.rb', line 303 def category taxons.joins(:taxonomy). where(spree_taxonomies: { name: Spree.t(:taxonomy_categories_name) }). order(depth: :desc). first end |
#default_variant ⇒ Spree::Variant
Returns default Variant for Product If ‘track_inventory_levels` is enabled it will try to find the first Variant in stock or backorderable, if there’s none it will return first Variant sorted by ‘position` attribute If `track_inventory_levels` is disabled it will return first Variant sorted by `position` attribute
162 163 164 165 166 167 168 169 170 171 172 |
# File 'app/models/spree/product.rb', line 162 def default_variant track_inventory = Spree::Config[:track_inventory_levels] Rails.cache.fetch("spree/default-variant/#{cache_key_with_version}/#{track_inventory}") do if track_inventory && variants.in_stock_or_backorderable.any? variants.in_stock_or_backorderable.first else has_variants? ? variants.first : master end end end |
#default_variant_id ⇒ Integer
Returns default Variant ID for Product
176 177 178 |
# File 'app/models/spree/product.rb', line 176 def default_variant_id default_variant.id 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.
211 212 213 |
# File 'app/models/spree/product.rb', line 211 def deleted? !!deleted_at end |
#discontinue! ⇒ Object
222 223 224 |
# File 'app/models/spree/product.rb', line 222 def discontinue! update_attribute(:discontinue_on, Time.current) end |
#discontinued? ⇒ Boolean
226 227 228 |
# File 'app/models/spree/product.rb', line 226 def discontinued? !!discontinue_on && discontinue_on <= Time.current end |
#duplicate ⇒ Object
for adding products which are closely related to existing ones define “duplicate_extra” for site-specific actions, eg for additional fields
203 204 205 206 |
# File 'app/models/spree/product.rb', line 203 def duplicate duplicator = ProductDuplicator.new(self) duplicator.duplicate end |
#empty_option_values? ⇒ Boolean
264 265 266 267 268 |
# File 'app/models/spree/product.rb', line 264 def empty_option_values? .empty? || .any? do |opt| opt.option_type.option_values.empty? end end |
#ensure_option_types_exist_for_values_hash ⇒ Object
Ensures option_types and product_option_types exist for keys in option_values_hash
191 192 193 194 195 196 197 198 199 |
# File 'app/models/spree/product.rb', line 191 def ensure_option_types_exist_for_values_hash return if option_values_hash.nil? required_option_type_ids = option_values_hash.keys.map(&:to_i) missing_option_type_ids = required_option_type_ids - option_type_ids missing_option_type_ids.each do |id| product_option_types.create(option_type_id: id) end end |
#find_or_build_master ⇒ Object
145 146 147 |
# File 'app/models/spree/product.rb', line 145 def find_or_build_master master || build_master end |
#has_variants? ⇒ Boolean
the master variant is not a member of the variants array
150 151 152 |
# File 'app/models/spree/product.rb', line 150 def has_variants? variants.any? end |
#in_stock? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259
136 137 138 |
# File 'app/models/spree/product.rb', line 136 def in_stock? variants_including_master.any?(&:in_stock?) end |
#master ⇒ Object
Master variant may be deleted (i.e. when the product is deleted) which would make AR’s default finder return nil. This is a stopgap for that little problem.
295 296 297 |
# File 'app/models/spree/product.rb', line 295 def master super || variants_including_master.with_deleted.find_by(is_master: true) end |
#property(property_name) ⇒ Object
270 271 272 |
# File 'app/models/spree/product.rb', line 270 def property(property_name) product_properties.joins(:property).find_by(spree_properties: { name: property_name }).try(:value) end |
#purchasable? ⇒ Boolean
Cant use short form block syntax due to github.com/Netflix/fast_jsonapi/issues/259
131 132 133 |
# File 'app/models/spree/product.rb', line 131 def purchasable? variants_including_master.any?(&:purchasable?) end |
#set_property(property_name, property_value, property_presentation = property_name) ⇒ Object
274 275 276 277 278 279 280 281 282 |
# File 'app/models/spree/product.rb', line 274 def set_property(property_name, property_value, property_presentation = property_name) ApplicationRecord.transaction do # Works around spree_i18n #301 property = Property.create_with(presentation: property_presentation).find_or_create_by(name: property_name) product_property = ProductProperty.where(product: self, property: property).first_or_initialize product_property.value = property_value product_property.save! end end |
#tax_category ⇒ Object
180 181 182 |
# File 'app/models/spree/product.rb', line 180 def tax_category super || TaxCategory.find_by(is_default: true) end |
#total_on_hand ⇒ Object
284 285 286 287 288 289 290 |
# File 'app/models/spree/product.rb', line 284 def total_on_hand if any_variants_not_track_inventory? Float::INFINITY else stock_items.sum(:count_on_hand) end end |
#variants_and_option_values(current_currency = nil) ⇒ Object
Suitable for displaying only variants that has at least one option value. There may be scenarios where an option type is removed and along with it all option values. At that point all variants associated with only those values should not be displayed to frontend users. Otherwise it breaks the idea of having variants
260 261 262 |
# File 'app/models/spree/product.rb', line 260 def variants_and_option_values(current_currency = nil) variants.active(current_currency).joins(:option_value_variants) end |