Automatic BOGO + discount code

2 0 0


We are trying to run a BOGO sale via scripts on available to items only in a specific collection. We would not like to have promo codes able to be applied to the BOGO pairs, but do want to let them apply to items outside the collection or, for instance, if they bought just one item from the BOGO collection. Can anyone provide any assistance? I have scripts for BOGO on all items and automatic discounts, but do not have enough experience to write what we're trying to accomplish. Thanks!

Replies 2 (2)
Shopify Partner
140 1 23

Hey Mate,


Could you post the BOGO script you're currently using. I can give you some advice on what needs changing to get this working.




Feeling a bit lost? Contact for help with theme setup, alterations, custom functionality, and app development.
2 0 0

# Returns the integer amount of items that must be discounted next
# given the amount of items seen

#if Input.cart.discount_code !=nil ## Commented out - if left in will either apply promo code if input, or run BOGO Script
# Output.cart = Input.cart
# .exit
# end

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

# 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 = / 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_seen += line_item.quantity
# 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_seen += discounted_item.quantity

# Return the items to be discounted

eligible_items = do |line_item|
product = line_item.variant.product
!product.gift_card? && product.tags.include?('bogo')# added product tags for specific collection hopefully#&& == 10779999630 - Commented out, instead a specific item, apply to all

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 FREE")

Output.cart = Input.cart