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
127
128
|
# File 'app/models/spree/variant.rb', line 124
def self.product_name_or_sku_cont(query)
joins(:product).join_translation_table(Product).
where("LOWER(#{Product.translation_table_alias}.name) LIKE LOWER(:query)
OR LOWER(sku) LIKE LOWER(:query)", query: "%#{query}%")
end
|
.search_by_product_name_or_sku(query) ⇒ Object
130
131
132
|
# File 'app/models/spree/variant.rb', line 130
def self.search_by_product_name_or_sku(query)
product_name_or_sku_cont(query)
end
|
Instance Method Details
#amount_in(currency) ⇒ Object
234
235
236
|
# File 'app/models/spree/variant.rb', line 234
def amount_in(currency)
price_in(currency).try(:amount)
end
|
#available? ⇒ Boolean
134
135
136
|
# File 'app/models/spree/variant.rb', line 134
def available?
!discontinued? && product.available?
end
|
#backorderable? ⇒ Boolean
Also known as:
is_backorderable?
290
291
292
293
294
|
# File 'app/models/spree/variant.rb', line 290
def backorderable?
@backorderable ||= Rails.cache.fetch(['variant-backorderable', cache_key_with_version]) do
quantifier.backorderable?
end
end
|
#backordered? ⇒ Boolean
326
327
328
|
# File 'app/models/spree/variant.rb', line 326
def backordered?
@backordered ||= !in_stock? && stock_items.exists?(backorderable: true)
end
|
#compare_at_amount_in(currency) ⇒ Object
238
239
240
|
# File 'app/models/spree/variant.rb', line 238
def compare_at_amount_in(currency)
price_in(currency).try(:compare_at_amount)
end
|
#compare_at_price ⇒ Object
268
269
270
|
# File 'app/models/spree/variant.rb', line 268
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.
166
167
168
|
# File 'app/models/spree/variant.rb', line 166
def deleted?
!!deleted_at
end
|
#descriptive_name ⇒ Object
159
160
161
|
# File 'app/models/spree/variant.rb', line 159
def descriptive_name
is_master? ? name + ' - Master' : name + ' - ' + options_text
end
|
#digital? ⇒ Boolean
Is this variant to be downloaded by the customer?
331
332
333
|
# File 'app/models/spree/variant.rb', line 331
def digital?
digitals.present?
end
|
#dimension ⇒ Object
314
315
316
|
# File 'app/models/spree/variant.rb', line 314
def dimension
(width || 0) + (height || 0) + (depth || 0)
end
|
#discontinue! ⇒ Object
318
319
320
|
# File 'app/models/spree/variant.rb', line 318
def discontinue!
update_attribute(:discontinue_on, Time.current)
end
|
#discontinued? ⇒ Boolean
322
323
324
|
# File 'app/models/spree/variant.rb', line 322
def discontinued?
!!discontinue_on && discontinue_on <= Time.current
end
|
#exchange_name ⇒ Object
155
156
157
|
# File 'app/models/spree/variant.rb', line 155
def exchange_name
is_master? ? name : options_text
end
|
#find_option_value(opt_name) ⇒ Object
209
210
211
|
# File 'app/models/spree/variant.rb', line 209
def find_option_value(opt_name)
option_values.detect { |o| o.option_type.name.downcase.strip == opt_name.downcase.strip }
end
|
#in_stock? ⇒ Boolean
280
281
282
283
284
285
286
287
288
|
# File 'app/models/spree/variant.rb', line 280
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
138
139
140
|
# File 'app/models/spree/variant.rb', line 138
def in_stock_or_backorderable?
self.class.in_stock_or_backorderable.exists?(id: id)
end
|
#name_and_sku ⇒ Object
272
273
274
|
# File 'app/models/spree/variant.rb', line 272
def name_and_sku
"#{name} - #{sku}"
end
|
#option_value(opt_name) ⇒ Object
213
214
215
|
# File 'app/models/spree/variant.rb', line 213
def option_value(opt_name)
find_option_value(opt_name).try(:presentation)
end
|
#options=(options = {}) ⇒ Object
170
171
172
173
174
175
176
|
# File 'app/models/spree/variant.rb', line 170
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'app/models/spree/variant.rb', line 217
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
255
256
257
258
259
260
261
262
263
264
265
266
|
# File 'app/models/spree/variant.rb', line 255
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
242
243
244
245
246
247
248
249
250
251
252
253
|
# File 'app/models/spree/variant.rb', line 242
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
300
301
302
|
# File 'app/models/spree/variant.rb', line 300
def purchasable?
@purchasable ||= in_stock? || backorderable?
end
|
#set_option_value(opt_name, opt_value) ⇒ Object
178
179
180
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
|
# File 'app/models/spree/variant.rb', line 178
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
306
307
308
|
# File 'app/models/spree/variant.rb', line 306
def should_track_inventory?
track_inventory? && Spree::Config.track_inventory_levels
end
|
#sku_and_options_text ⇒ Object
276
277
278
|
# File 'app/models/spree/variant.rb', line 276
def sku_and_options_text
"#{sku} #{options_text}".strip
end
|
#tax_category ⇒ Object
142
143
144
145
146
147
148
|
# File 'app/models/spree/variant.rb', line 142
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
310
311
312
|
# File 'app/models/spree/variant.rb', line 310
def volume
(width || 0) * (height || 0) * (depth || 0)
end
|