How to modify script for rounding down discounts?

Topic summary

A user is troubleshooting a Ruby discount script that rounds prices up instead of down. The issue centers on line 24 of the code, which uses .ceil (ceiling function) to round up.

Solution provided:

  • Change .ceil to .floor in the calculation
  • .floor rounds decimals down to the lowest integer, while .ceil rounds up

Follow-up request:
The original poster asks how to restrict the script to work with only one specific discount code, rather than applying to all codes ending with a number.

Additional guidance:

  • Create an array of affected discount codes (e.g., affected_discount_codes = ["TESTCODE12"])
  • Add a conditional check in the run method to verify if the cart’s discount code is included in that list
  • Only apply the discount logic when the code matches

The discussion remains open, with one participant asking where to apply this code.

Summarized with AI on November 25. AI used: claude-sonnet-4-5-20250929.

Hi - I’ve created this script however the discount is rounding up to the nearest £ rather than down, please could someone advise how to change this?

class RoundedDiscountCampaign
def initialize(discount)
@discount = discount
end

def run(cart)
discount_amount = 0

if Input.cart.discount_code != nil
discount_amount = Input.cart.discount_code&.code.slice(-2,2)&.to_i
end

if discount_amount > 0
cart.line_items.each do |line_item|
@discount .apply(discount_amount, line_item)
end
end
end
end

class RoundedVariablePercentDiscount
def initialize(message)
@message = message
end

def apply(discount_amount, line_item)
updated_message = @message.sub ‘$amount’, discount_amount.to_s
round_up_price = ((line_item.line_price.cents * 0.01) * ((100 - discount_amount)/100)).ceil
new_price = Money.new(cents: round_up_price * 100)
line_item.change_line_price(new_price, message: updated_message)
end
end

CAMPAIGNS = [
RoundedDiscountCampaign.new(
RoundedVariablePercentDiscount.new(“$amount% off”)
)
]

CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end

Output.cart = Input.cart

Hi @jbrock93 ,

Your script is pretty close! It looks like the only change you may have to make is on line 24 inside your “apply” method. You need to call “floor” on the amount instead of “ceil”.

Change this:

round_up_price = ((line_item.line_price.cents * 0.01) * ((100 - discount_amount)/100)).ceil

to this;

round_up_price = ((line_item.line_price.cents * 0.01) * ((100 - discount_amount)/100)).floor

Calling “floor” on a decimal will round it down to the lowest integer, while calling “ceil” rounds it up. “ceil” is short for “ceiling” :slightly_smiling_face:

I haven’t had a chance to actually test your script, but see if that works for you. If it does, a “Like” and Accepted Solution would be great. I’ll post back once I’ve had a chance to test it.

@playwright-mike thanks Matt - I believe that has worked although is it possible to isolate this script to one discount code? (currently it applies to every code ending with a number and I would like it to work on one specific code only)

@jbrock93

I think I am still a little unclear about your overall approach, but I will do my best to answer your specific question.

You can modify your “run” method and add a check for certain codes. In the example below, I am basically providing a list of affected codes, and then checking to see if the Cart’s discount code is included in the list.

def run(cart)
    affected_discount_codes = ["TESTCODE12"]   # make a list of codes we want affected (currently just one code)
    discount_amount = 0

    unless Input.cart.discount_code.nil?
      discount_code_string = Input.cart.discount_code.code   # save the discount code as a string
      if affected_discount_codes.include?(discount_code_string)   # check to see if the code is in that list above
        discount_amount = discount_code_string.slice(-2, 2)&.to_i
      end
    end

    if discount_amount > 0
      cart.line_items.each do |line_item|
        @discount.apply(discount_amount, line_item)
      end
    end
  end

If you find that works, let me know!

Where ton apply this code?