Personalized checkout and custom promotions with Shopify Scripts
Any thoughts on how to optimize what we thought was a tidy solution to our need to discount products based on tagging? Better ways to simplify these nested loops we need to run? I'm very much a Ruby noob.
#object for lineitem campaigns
class XforYDollarsCampaign
#array of strings that are substrings to search against product tags
#int of threshold quantity, ex: 3 items to get the discount
#cents of pricedAt when matching discount, ex: 1500 = $15.00, so per item will be 1500/3, so $5 per item purchased
#discount message string
#matchCount for iterating the cart
attr_accessor :tagStrings, :threshholdQty, :pricedAt, :discountMsg, :matchCount
def initialize(tagStrings, threshholdQty, pricedAt, discountMsg)
@tagStrings = tagStrings
@threshholdQty = threshholdQty
@pricedAt = pricedAt
@discountMsg = discountMsg
@matchCount = 0
end
end
CAMPAIGNS = [
XforYDollarsCampaign.new(["2_for_5"], 2, 500, "2 for $5"),
XforYDollarsCampaign.new(["2_or_more_5"], 2, 1000, "$5 when buying 2 or more"),
XforYDollarsCampaign.new(["2_for_6"], 2, 600, "2 for $6"),
XforYDollarsCampaign.new(["2_or_more_6"], 2, 1200, "$6 when buying 2 or more"),
XforYDollarsCampaign.new(["2_for_7"], 2, 700, "2 for $7"),
XforYDollarsCampaign.new(["2_or_more_7"], 2, 1400, "$7 when buying 2 or more"),
XforYDollarsCampaign.new(["2_for_10"], 2, 1000, "2 for $10"),
XforYDollarsCampaign.new(["2_or_more_10", "10_dollar_2_or_more", "10_dollar_shoes_for_women"], 2, 2000, "$10 when buying 2 or more"),
XforYDollarsCampaign.new(["2_for_12"], 2, 1200, "2 for $12"),
XforYDollarsCampaign.new(["12_dollar_2_or_more"], 2, 2400, "$12 when buying 2 or more"),
XforYDollarsCampaign.new(["2_for_15"], 2, 1500, "2 for $15"),
XforYDollarsCampaign.new(["15_dollar_2_or_more"], 2, 3000, "$15 when buying 2 or more"),
XforYDollarsCampaign.new(["3_for_10"], 3, 1000, "3 for $10"),
XforYDollarsCampaign.new(["3_or_more_10", "10_dollar_3_or_more"], 3, 3000, "$10 when buying 3 or more"),
XforYDollarsCampaign.new(["3_for_15"], 3, 1500, "3 for $15"),
XforYDollarsCampaign.new(["15_dollar_3_or_more"], 3, 4500, "$15 when buying 3 or more"),
XforYDollarsCampaign.new(["10_dollar_4_or_more"], 4, 4000, "$10 when buying 4 or more"),
XforYDollarsCampaign.new(["5_for_10"], 5, 1000, "5 for $10"),
XforYDollarsCampaign.new(["10_dollar_5_or_more"], 5, 5000, "$10 when buying 5 or more")
].freeze
line_items = Input.cart.line_items
#function findMatches (find and prep the matches, populate the CAMPAIGNS array with those lineitems)
#get qty amounts of products that match the tags
#puts ("Loozp em")
line_items.each do |line_item|
CAMPAIGNS.each do |campaign|
campaign.tagStrings.each do |thisTagString|
#puts (line_item.variant.product.tags)
if line_item.variant.product.tags.any? { |productTag| productTag.include?(thisTagString) }
campaign.matchCount += line_item.quantity
#puts ("GOT ONE HOLY SHIT #{line_item.variant.product}")
end
end #end campaign.tagStrings loop
end #end CAMPAIGNS loop
end #end sorted_items
#run that function, then cycle through the lineitems in cart again and price/message accordingly
line_items.each do |line_item|
lineItemIsDiscounted = false
CAMPAIGNS.each do |campaign|
campaign.tagStrings.each do |thisTagString|
#puts (line_item.variant.product.tags)
if line_item.variant.product.tags.any? { |productTag| productTag.include?(thisTagString) }
#we have a match again, now check this campaign,
if campaign.matchCount >= campaign.threshholdQty
perItemCents = campaign.pricedAt / campaign.threshholdQty
#puts (perItemCents)
updatedPrice = Money.new(cents: (perItemCents * line_item.quantity)) #set that price!
if(updatedPrice < line_item.original_line_price)
line_item.change_line_price(updatedPrice, {message: campaign.discountMsg}) #set that msg!
end
lineItemIsDiscounted = true
break #stop cycling campaign strings, we have a winner
end
end
end
if lineItemIsDiscounted
break #stop cycling campaigns
end
end
#continue to next lineitem
end
Output.cart = Input.cart
June brought summer energy to our community. Members jumped in with solutions, clicked ...
By JasonH Jun 5, 2025Learn how to build powerful custom workflows in Shopify Flow with expert guidance from ...
By Jacqui May 7, 2025Did You Know? May is named after Maia, the Roman goddess of growth and flourishing! ...
By JasonH May 2, 2025