app/models/concerns/spree/product_on_salable.rb
module Spree
module ProductOnSalable
extend ActiveSupport::Concern
included do
has_many :sale_prices, through: :prices
# Essentially all read values here are delegated to reading the value on the Master variant
# All write values will write to all variants (including the Master) unless that method's all_variants parameter is set to false, in which case it will only write to the Master variant
delegate :active_sale_in, :current_sale_in, :next_active_sale_in, :next_current_sale_in,
:sale_price_in, :on_sale_in?, :original_price_in, :discount_percent_in, :sale_price,
:original_price, :on_sale?, to: :master
# Entrega los productos con descuento
scope :in_sale, -> {
joins(master: :sale_prices)
.where(spree_sale_prices: {enabled: true})
.where("spree_sale_prices.value < spree_prices.amount")
.where("spree_sale_prices.start_at <= ? OR spree_sale_prices.start_at IS NULL", Time.now)
.where("spree_sale_prices.end_at >= ? OR spree_sale_prices.end_at IS NULL", Time.now)
.uniq
}
end
# TODO: also accept a class reference for calculator type instead of only a string
def put_on_sale value, params={}
if !params[:variant] || (params[:variant] == "all_variants") || (params[:variant] == :all_variants)
run_on_variants(true) {|v| v.put_on_sale(value, params) }
elsif params[:variant]
variants_including_master.find(params[:variant]).put_on_sale(value, params) if variants_including_master.exists?(id: params[:variant])
end
touch
end
alias create_sale put_on_sale
def enable_sale(all_variants=true)
run_on_variants(all_variants, &:enable_sale)
end
def disable_sale(all_variants=true)
run_on_variants(all_variants, &:disable_sale)
end
def start_sale(end_time=nil, all_variants=true)
run_on_variants(all_variants) {|v| v.start_sale(end_time) }
end
def stop_sale(all_variants=true)
run_on_variants(all_variants, &:stop_sale)
end
private
def run_on_variants(all_variants)
variants.each {|v| yield v } if all_variants && variants.present?
yield master
end
end
end