Class: Spree::Variant
Constant Summary
collapse
- MEMOIZED_METHODS =
%w(purchasable in_stock backorderable tax_category options_text compare_at_price)
- LOCALIZED_NUMBERS =
FIXME: cost price should be represented with DisplayMoney class
%w(cost_price weight depth width height)
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Base
belongs_to_required_by_default, for_store, has_many_inversing, json_api_columns, json_api_permitted_attributes, json_api_type, page, spree_base_scopes, spree_base_uniqueness_scope
#clear_preferences, #default_preferences, #defined_preferences, #deprecated_preferences, #get_preference, #has_preference!, #has_preference?, #preference_default, #preference_deprecated, #preference_type, #set_preference
Class Method Details
.product_name_or_sku_cont(query) ⇒ Object
124
125
126
|
# File 'app/models/spree/variant.rb', line 124
def self.product_name_or_sku_cont(query)
joins(:product).where("LOWER(#{Product.table_name}.name) LIKE LOWER(:query) OR LOWER(sku) LIKE LOWER(:query)", query: "%#{query}%")
end
|
.search_by_product_name_or_sku(query) ⇒ Object
128
129
130
131
132
133
134
135
|
# File 'app/models/spree/variant.rb', line 128
def self.search_by_product_name_or_sku(query)
if defined?(SpreeGlobalize)
joins(product: :translations).where("LOWER(#{Product::Translation.table_name}.name) LIKE LOWER(:query) OR LOWER(sku) LIKE LOWER(:query)",
query: "%#{query}%")
else
product_name_or_sku_cont(query)
end
end
|
Instance Method Details
#amount_in(currency) ⇒ Object
237
238
239
|
# File 'app/models/spree/variant.rb', line 237
def amount_in(currency)
price_in(currency).try(:amount)
end
|
#available? ⇒ Boolean
137
138
139
|
# File 'app/models/spree/variant.rb', line 137
def available?
!discontinued? && product.available?
end
|
#backorderable? ⇒ Boolean
Also known as:
is_backorderable?
293
294
295
296
297
|
# File 'app/models/spree/variant.rb', line 293
def backorderable?
@backorderable ||= Rails.cache.fetch(['variant-backorderable', cache_key_with_version]) do
quantifier.backorderable?
end
end
|
#backordered? ⇒ Boolean
329
330
331
|
# File 'app/models/spree/variant.rb', line 329
def backordered?
@backordered ||= !in_stock? && stock_items.exists?(backorderable: true)
end
|
#compare_at_amount_in(currency) ⇒ Object
241
242
243
|
# File 'app/models/spree/variant.rb', line 241
def compare_at_amount_in(currency)
price_in(currency).try(:compare_at_amount)
end
|
#compare_at_price ⇒ Object
271
272
273
|
# File 'app/models/spree/variant.rb', line 271
def compare_at_price
@compare_at_price ||= price_in(cost_currency).try(:compare_at_amount)
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.
169
170
171
|
# File 'app/models/spree/variant.rb', line 169
def deleted?
!!deleted_at
end
|
#descriptive_name ⇒ Object
162
163
164
|
# File 'app/models/spree/variant.rb', line 162
def descriptive_name
is_master? ? name + ' - Master' : name + ' - ' + options_text
end
|
#digital? ⇒ Boolean
Is this variant to be downloaded by the customer?
334
335
336
|
# File 'app/models/spree/variant.rb', line 334
def digital?
digitals.present?
end
|
#dimension ⇒ Object
317
318
319
|
# File 'app/models/spree/variant.rb', line 317
def dimension
(width || 0) + (height || 0) + (depth || 0)
end
|
#discontinue! ⇒ Object
321
322
323
|
# File 'app/models/spree/variant.rb', line 321
def discontinue!
update_attribute(:discontinue_on, Time.current)
end
|
#discontinued? ⇒ Boolean
325
326
327
|
# File 'app/models/spree/variant.rb', line 325
def discontinued?
!!discontinue_on && discontinue_on <= Time.current
end
|
#exchange_name ⇒ Object
158
159
160
|
# File 'app/models/spree/variant.rb', line 158
def exchange_name
is_master? ? name : options_text
end
|
#find_option_value(opt_name) ⇒ Object
212
213
214
|
# File 'app/models/spree/variant.rb', line 212
def find_option_value(opt_name)
option_values.detect { |o| o.option_type.name.downcase.strip == opt_name.downcase.strip }
end
|
#in_stock? ⇒ Boolean
283
284
285
286
287
288
289
290
291
|
# File 'app/models/spree/variant.rb', line 283
def in_stock?
version = respond_to?(:cache_version) ? cache_version : updated_at.to_i
@in_stock ||= Rails.cache.fetch(in_stock_cache_key, version: version) do
total_on_hand > 0
end
end
|
#in_stock_or_backorderable? ⇒ Boolean
141
142
143
|
# File 'app/models/spree/variant.rb', line 141
def in_stock_or_backorderable?
self.class.in_stock_or_backorderable.exists?(id: id)
end
|
#name_and_sku ⇒ Object
275
276
277
|
# File 'app/models/spree/variant.rb', line 275
def name_and_sku
"#{name} - #{sku}"
end
|
#option_value(opt_name) ⇒ Object
216
217
218
|
# File 'app/models/spree/variant.rb', line 216
def option_value(opt_name)
find_option_value(opt_name).try(:presentation)
end
|
#options=(options = {}) ⇒ Object
173
174
175
176
177
178
179
|
# File 'app/models/spree/variant.rb', line 173
def options=(options = {})
options.each do |option|
next if option[:name].blank? || option[:value].blank?
set_option_value(option[:name], option[:value])
end
end
|
#price_in(currency) ⇒ Object
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
# File 'app/models/spree/variant.rb', line 220
def price_in(currency)
currency = currency&.upcase
find_or_build_price = lambda do
if prices.loaded?
prices.detect { |price| price.currency == currency } || prices.build(currency: currency)
else
prices.find_or_initialize_by(currency: currency)
end
end
Rails.cache.fetch("spree/prices/#{cache_key_with_version}/price_in/#{currency}") do
find_or_build_price.call
end
rescue TypeError
find_or_build_price.call
end
|
#price_modifier_amount(options = {}) ⇒ Object
258
259
260
261
262
263
264
265
266
267
268
269
|
# File 'app/models/spree/variant.rb', line 258
def price_modifier_amount(options = {})
return 0 unless options.present?
options.keys.map do |key|
m = "#{key}_price_modifier_amount".to_sym
if respond_to? m
send(m, options[key])
else
0
end
end.sum
end
|
#price_modifier_amount_in(currency, options = {}) ⇒ Object
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'app/models/spree/variant.rb', line 245
def price_modifier_amount_in(currency, options = {})
return 0 unless options.present?
options.keys.map do |key|
m = "#{key}_price_modifier_amount_in".to_sym
if respond_to? m
send(m, currency, options[key])
else
0
end
end.sum
end
|
#purchasable? ⇒ Boolean
303
304
305
|
# File 'app/models/spree/variant.rb', line 303
def purchasable?
@purchasable ||= in_stock? || backorderable?
end
|
#set_option_value(opt_name, opt_value) ⇒ Object
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'app/models/spree/variant.rb', line 181
def set_option_value(opt_name, opt_value)
return if is_master
option_type = Spree::OptionType.where(['LOWER(name) = ?', opt_name.downcase.strip]).first_or_initialize do |o|
o.name = o.presentation = opt_name
o.save!
end
current_value = find_option_value(opt_name)
if current_value.nil?
unless product.option_types.include? option_type
product.option_types << option_type
end
else
return if current_value.name.downcase.strip == opt_value.downcase.strip
option_values.delete(current_value)
end
option_value = option_type.option_values.where(['LOWER(name) = ?', opt_value.downcase.strip]).first_or_initialize do |o|
o.name = o.presentation = opt_value
o.save!
end
option_values << option_value
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
309
310
311
|
# File 'app/models/spree/variant.rb', line 309
def should_track_inventory?
track_inventory? && Spree::Config.track_inventory_levels
end
|
#sku_and_options_text ⇒ Object
279
280
281
|
# File 'app/models/spree/variant.rb', line 279
def sku_and_options_text
"#{sku} #{options_text}".strip
end
|
#tax_category ⇒ Object
145
146
147
148
149
150
151
|
# File 'app/models/spree/variant.rb', line 145
def tax_category
@tax_category ||= if self[:tax_category_id].nil?
product.tax_category
else
Spree::TaxCategory.find_by(id: self[:tax_category_id]) || product.tax_category
end
end
|
#volume ⇒ Object
313
314
315
|
# File 'app/models/spree/variant.rb', line 313
def volume
(width || 0) * (height || 0) * (depth || 0)
end
|