Module: Models::SaleDiscountable

Extended by:
ActiveSupport::Concern
Included in:
CatalogItem, ViewProductCatalog
Defined in:
app/concerns/models/sale_discountable.rb

Overview

ActiveSupport::Concern mixin: sale discountable.

Adds sale-price helpers to models carrying price/sale_price columns
(regular amount, sale amount, effective price honoring sale date windows,
and their Money-wrapped variants).

Instance Method Summary collapse

Instance Method Details

#amountBigDecimal

The base (non-sale) amount, preferring price when the model exposes it.

Returns:

  • (BigDecimal)

    the regular price



16
17
18
19
20
# File 'app/concerns/models/sale_discountable.rb', line 16

def amount
  return price if respond_to?(:price)

  super
end

#effective_priceBigDecimal

The currently applicable price.

Returns:

  • (BigDecimal)

    the sale price if in effect, otherwise the regular amount



48
49
50
# File 'app/concerns/models/sale_discountable.rb', line 48

def effective_price
  (sale_price if sale_price_in_effect?) || amount
end

#money_effective_priceMoney

The currently applicable price wrapped in a Money object.

Returns:

  • (Money)

    the sale price if in effect, otherwise the regular price



41
42
43
# File 'app/concerns/models/sale_discountable.rb', line 41

def money_effective_price
  (money_sale_price if sale_price_in_effect?) || money_price
end

#money_priceMoney

The base amount wrapped in a Money object.

Returns:

  • (Money)

    the regular price as money



25
26
27
# File 'app/concerns/models/sale_discountable.rb', line 25

def money_price
  Money.new(amount * 100, currency)
end

#money_sale_priceMoney?

The sale price wrapped in a Money object.

Returns:

  • (Money, nil)

    the sale price as money, or nil when no sale price is set



32
33
34
35
36
# File 'app/concerns/models/sale_discountable.rb', line 32

def money_sale_price
  return unless sale_price

  Money.new(sale_price * 100, currency)
end

#sale_price_in_effect?(exclude_effective_date: false, date_to_check: nil) ⇒ Boolean

Whether the sale price is currently in effect.

Parameters:

  • exclude_effective_date (Boolean) (defaults to: false)

    skip the sale date-window check

  • date_to_check (Date, nil) (defaults to: nil)

    date to evaluate against the sale window
    (defaults to Date.current)

Returns:

  • (Boolean)

    true if a sale price is set and (unless excluded) the
    checked date falls within the effective/expiration window



59
60
61
62
63
64
65
66
67
68
69
70
# File 'app/concerns/models/sale_discountable.rb', line 59

def sale_price_in_effect?(exclude_effective_date: false, date_to_check: nil)
  return false if sale_price.blank?

  unless exclude_effective_date
    date_to_check ||= Date.current
    # If today is before the sale start, don't send
    return false if sale_price_effective_date && date_to_check < sale_price_effective_date
    # If today is past the sale expiration, don't send
    return false if sale_price_expiration_date && date_to_check > sale_price_expiration_date
  end
  true
end

#sale_price_percentage_offFloat

Percentage discount the sale price represents off the regular amount.

Returns:

  • (Float)

    percentage off, rounded to 2 decimals; 0.0 when no sale
    price or amount is set



76
77
78
79
80
# File 'app/concerns/models/sale_discountable.rb', line 76

def sale_price_percentage_off
  return 0.0 unless sale_price.present? && amount.present?

  ((1.0 - (sale_price / amount)) * 100).round(2)
end