Hi guys, I have a shopify script that I need to modify slightly. This script was built by someone else, with a lot more experience in Ruby and Shopify scripting. Also, he worked on this many years ago and I can’t really contact him anymore. I tried modifying it myself, but I couldn’t figure it out.
What our script does right now, it is a golden ticket script. When someone types in a special discount code, they will get the item for 100% free. If there are multiple items, it will just choose the cheapest and make that one free. If they only have one item in their cart, it will make that item free and they could checkout with no payment information.
I will paste the scrip below (I’m going to remove all the real golden codes of course).
The modification that I want to make, I want to add a maximum dollar amount that can be discounted. It will be $150. So if they try to order a $500 product, instead of it discounting the entire $500, it will just take $150 off, and make the product $350.
I can show you guys what I was trying to to do, I was trying to edit the first few lines, the first if else code, but it wasn’t working.
Here is our script:
if Input.cart.line_items.size > 0 and Input.cart.discount_code != nil
freebie_discount_codes = ["fake234", "fake1234", "fake12345", "fake1233", etc]
if freebie_discount_codes.include?(Input.cart.discount_code.code)
if Input.cart.line_items.size == 1 && Input.cart.line_items.first.quantity == 1
Input.cart.line_items.select do |line_item|
line_item.change_line_price(Money.new(cents: 1), message: @discount_message)
end
else
freebie_product_price = Money.zero
freebie_product_id = 0
Input.cart.line_items.select do |line_item|
if freebie_product_price == Money.zero
freebie_product_price = line_item.variant.price
freebie_product_id = line_item.variant.id
end
if line_item.variant.price < freebie_product_price
freebie_product_id = line_item.variant.id
freebie_product_price = line_item.variant.price
end
end
PRODUCT_DISCOUNTS_BY_DISCOUNT_CODE = [
{
discount_code_match_type: :exact,
discount_codes: freebie_discount_codes,
product_selector_match_type: :include,
# product_selector_type: :all,
# product_selectors: 'nil', #[freebie_product_id],
product_selector_type: :variant_id,
product_selectors: [freebie_product_id],
discount_type: :dollar,
discount_amount: freebie_product_price,
discount_message: 'GOLDEN TICKET'
}
]
# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountCodeSelector
#
# Finds whether the supplied discount code matches any of the
# entered codes.
# ================================================================
class DiscountCodeSelector
def initialize(match_type, discount_codes)
@comparator = match_type == :exact ? '==' : 'include?'
@discount_codes = discount_codes.map { |discount_code| discount_code.upcase.strip }
end
def match?(discount_code)
!@discount_codes.empty? { |code| discount_code.code.upcase.send(@comparator, code) }
end
end
# ================================================================
# ProductSelector
#
# Finds matching products by the entered criteria.
# ================================================================
class ProductSelector
def initialize(match_type, selector_type, selectors)
@match_type = match_type
@comparator = match_type == :include ? 'any?' : 'none?'
@selector_type = selector_type
@selectors = selectors
end
def match?(line_item)
if self.respond_to?(@selector_type)
self.send(@selector_type, line_item)
else
raise RuntimeError.new('Invalid product selector type')
end
end
def tag(line_item)
product_tags = line_item.variant.product.tags.map { |tag| tag.downcase.strip }
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@selectors & product_tags).send(@comparator)
end
def type(line_item)
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@match_type == :include) == @selectors.include?(line_item.variant.product.product_type.downcase.strip)
end
def vendor(line_item)
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@match_type == :include) == @selectors.include?(line_item.variant.product.vendor.downcase.strip)
end
def product_id(line_item)
(@match_type == :include) == @selectors.include?(line_item.variant.product.id)
end
def variant_id(line_item)
@selectors.include?(line_item.variant.id)
end
def all(line_item)
true
end
end
# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied line item.
# ================================================================
class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)
@discount_type = discount_type
@discount_message = discount_message
@discount_amount = if discount_type == :percent
1 - (discount_amount * 0.01)
else
discount_amount
end
end
def apply(line_item)
new_line_price = if @discount_type == :percent
line_item.line_price * @discount_amount
else
[line_item.line_price - @discount_amount, Money.zero].max
end
line_item.change_line_price(new_line_price, message: @discount_message)
end
end
# ================================================================
# ProductDiscountByCodeCampaign
#
# If any "matching" discount codes are used, any "matching" product
# will be discounted by the entered amount.
# ================================================================
class ProductDiscountByCodeCampaign
def initialize(campaigns)
@campaigns = campaigns
end
def run(cart)
return if cart.discount_code.nil?
@campaigns.each do |campaign|
discount_code_selector = DiscountCodeSelector.new(
campaign[:discount_code_match_type],
campaign[:discount_codes]
)
next unless discount_code_selector.match?(cart.discount_code)
product_selector = ProductSelector.new(
campaign[:product_selector_match_type],
campaign[:product_selector_type],
campaign[:product_selectors],
)
discount_applicator = DiscountApplicator.new(
campaign[:discount_type],
campaign[:discount_amount],
campaign[:discount_message]
)
cart.line_items.each do |line_item|
next unless product_selector.match?(line_item)
discount_applicator.apply(line_item)
end
end
end
end
CAMPAIGNS = [
ProductDiscountByCodeCampaign.new(PRODUCT_DISCOUNTS_BY_DISCOUNT_CODE),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
end
end
end
Output.cart = Input.cart
How the script works, is it sets the price of the item to 1 cent.
Then those special coupon code, they are just a code on Shopify side that removes one cent. Thus making it free.
Thanks so much for all the help anyone can provide.