Dan Mitchell
Dan Mitchell

Reputation: 864

Rails, get discount amount from 2 helpers

I have small rails shop and with the following to helpers to work out total price and the discount if one has been applied but I want to work out what the actual discount is to display in the view -

  def total_price
    price = 0
    order_products.each do |order_products|
      # add the item price to total
      price += (order_products.price_in_pence * order_products.quantity)
    end
    apply_discount(price)
  end

  def apply_discount(price)
    return price if discount.nil?
    if discount.percentage.present?
      price = price - ((price / 100) * discount.percentage)
    elsif discount.money.present?
      price = price - discount.money
    end
    price < 0 ? 0 : price
  end

  def discount_amount
    I need something here to take the total_price from above 
    before a discount and then the apply_discount and subtract the 2.
  end

Upvotes: 0

Views: 1373

Answers (3)

Vu Minh Tan
Vu Minh Tan

Reputation: 526

You should refactor the price before discount into a private method to reuse:

  def total_price    
    apply_discount(price_before_discount)
  end

  def apply_discount(price)
    return price if discount.nil?
    if discount.percentage.present?
      price = price - ((price / 100) * discount.percentage)
    elsif discount.money.present?
      price = price - discount.money
    end
    price < 0 ? 0 : price
  end

  def discount_amount
    price_before_discount - total_price
  end

  private
    def price_before_discount
      @price_before_discount ||= order_products.inject(0) do |sum, order_product|
      # add the item price to total
        sum += (order_product.price_in_pence * order_product.quantity)
      end
    end

Upvotes: 1

Stefan
Stefan

Reputation: 114188

I would move the calculation into the discount_amount method:

def total_price
  order_products.inject(0) do |sum, product|
    sum + (product.price_in_pence * product.quantity)
  end
end

def discount_amount
  return 0 unless discount
  if discount.percentage.present?
    (total_price / 100) * discount.percentage
  elsif discount.money.present?
    discount.money
  end
end

def total_price_after_discount
  total_price - discount_amount
end

Upvotes: 1

gdpelican
gdpelican

Reputation: 568

Not sure where you're getting discount from in apply_discount, but seems to me as though you want four values available:

  • price
  • percentage discount
  • flat discount
  • total

So, maybe something like this?

def price
  order_productions.each { |p| p.price * p.quantity }
end

def percent_discount
  1 - (discount.percentage || 0) # ie, 100% [or 0% off] when discount.percentage is nil
end

def flat_discount
  discount.money || 0 # (ie, 0 dollars off)
end

def total
  [(price * percent_discount) - flat_discount, 0].max # to ensure we get a positive value
end

(NB: untested)

(You may need to tweak a bit for the case [if it is a case] that a discount has both a percentage and a flat amount on it, or if discount can be nil.)

Upvotes: 1

Related Questions