Personalized checkout and custom promotions with Shopify Scripts
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" 🙂
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)
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?
Learn how to expand your operations internationally with Shopify Academy’s learning path...
By Shopify Feb 4, 2025Hey Community, happy February! Looking back to January, we kicked off the year with 8....
By JasonH Feb 3, 2025Expand into selling wholesale with Shopify Academy’s learning path, B2B on Shopify: Lau...
By Shopify Jan 28, 2025