Forked from dylanjhunt/Shopify Scripts - Buy 2 get 1 free
Last active
November 14, 2017 21:43
-
-
Save discernmarketing/4f7608392d6fa149b2efd305b02de955 to your computer and use it in GitHub Desktop.
Buy 2 get 1 free Shopify Script. More similar scripts to be downloaded here: https://liquidandscripts.com/collections/free-shopify-scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PAID_ITEM_COUNT = 5 | |
DISCOUNTED_ITEM_COUNT = 1 | |
# 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 | |
# 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 | |
checkout = Input.cart | |
# Checkout to look for discount codes | |
eligible_items = Input.cart.line_items.select do |line_item| | |
product = line_item.variant.product | |
!product.gift_card? && (product.id == XXX || product.id == XXX || product.id == XXX || product.id == XXX) | |
# Multiple eligible items | |
end | |
discounted_line_items = partition(Input.cart, eligible_items) | |
discounted_line_items.each do |line_item| | |
line_item.change_line_price(Money.zero, message: "Buy 5, get 1 free") | |
if checkout.discount_code | |
checkout.discount_code.reject( | |
message: "Not eligible for discount." | |
) | |
# Exclude from discount codes | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment