Skip to content

Instantly share code, notes, and snippets.

@tjmapes
Created March 1, 2018 03:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tjmapes/8d879b4180c8382d671e446082070044 to your computer and use it in GitHub Desktop.
Save tjmapes/8d879b4180c8382d671e446082070044 to your computer and use it in GitHub Desktop.
Shopify Script - BOGO 50% OFF
PAID_ITEM_COUNT = 1
DISCOUNTED_ITEM_COUNT = 1
# ~~ Change 50 below to whatever percent you want the second item to be discounted at. Also, don't forget to change the message at the bottom
PERCENT_OFF = 50 # ~~ 50% OFF
# Returns the integer amount of items that must be discounted next
# given the amount of items seen
#
def discounted_items_to_find(total_items_seen, discounted_items_seen)
Integer(total_items_seen / (PAID_ITEM_COUNT + DISCOUNTED_ITEM_COUNT) * DISCOUNTED_ITEM_COUNT) - discounted_items_seen
end
# Partitions the items and returns the items that are to be discounted.
#
# Arguments
# ---------
#
# * cart
# The cart to which split items will be added (typically Input.cart).
#
# * line_items
# The selected items that are applicable for the campaign.
#
def partition(cart, line_items)
# Sort the items by price from high to low
sorted_items = line_items.sort_by{|line_item| line_item.variant.price}.reverse
# Create an array of items to return
discounted_items = []
# Keep counters of items seen and discounted, to avoid having to recalculate on each iteration
total_items_seen = 0
discounted_items_seen = 0
@percent = Decimal.new(PERCENT_OFF) / 100.0
# Loop over all the items and find those to be discounted
sorted_items.each do |line_item|
total_items_seen += line_item.quantity
# After incrementing total_items_seen, see if any items must be discounted
count = discounted_items_to_find(total_items_seen, discounted_items_seen)
# If there are none, skip to the next item
next if count <= 0
if count >= line_item.quantity
# If the full item quantity must be discounted, add it to the items to return
# and increment the count of discounted items
discounted_items.push(line_item)
discounted_items_seen += line_item.quantity
else
# If only part of the item must be discounted, split the item
discounted_item = line_item.split(take: count)
# Insert the newly-created item in the cart, right after the original item
position = cart.line_items.find_index(line_item)
cart.line_items.insert(position + 1, discounted_item)
# Add it to the list of items to return
discounted_items.push(discounted_item)
discounted_items_seen += discounted_item.quantity
end
end
# Return the items to be discounted
discounted_items
end
eligible_items = Input.cart.line_items.select do |line_item|
product = line_item.variant.product
tags = product.tags
unless product.gift_card?
product
end
end
discounted_line_items = partition(Input.cart, eligible_items)
discounted_line_items.each do |line_item|
line_discount = line_item.line_price * @percent
line_item.change_line_price(line_item.line_price - line_discount, message: "Buy one, get one 50% off")
end
#Output.cart = Input.cart
# Reject all discount codes
Output.cart = Input.cart
exit unless Input.cart.discount_code
Input.cart.discount_code.reject({ message: 'No discount codes allowed until promotion is over' })
Output.cart = Input.cart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment