Personalized checkout and custom promotions with Shopify Scripts
I am using script editor made by Shopify.
I want to disable discount codes for products that have "no_discount" tag but... Apply the discount on the rest of the prodcuts (imagine I have 5 products, but one of them with "no_discount" tag) Is this possible?
I'm trying with this script, but the closest I coud got is to block discount codes when product with mentioned tag is on the order, but this is not the expected result I want to.
# ================================ Customizable Settings ================================ # ================================================================ # Disable Discount Code(s) For Products # # If any matching discount codes are used, and any matching items # are in the cart, the discount code is rejected with the entered # message. # # - 'discount_code_match_type' determines whether the below # strings should be an exact or partial match. Can be: # - ':exact' for an exact match # - ':partial' for a partial match # - 'discount_codes' is a list of strings to identify discount # codes # - 'product_selector_match_type' determines whether we look for # products that do or don't match the entered selectors. Can # be: # - ':include' to check if the product does match # - ':exclude' to make sure the product doesn't match # - 'product_selector_type' determines how eligible products # will be identified. Can be either: # - ':tag' to find products by tag # - ':type' to find products by type # - ':vendor' to find products by vendor # - ':product_id' to find products by ID # - ':variant_id' to find products by variant ID # - ':subscription' to find subscription products # - ':all' for all products # - 'product_selectors' is a list of identifiers (from above) # for qualifying products. Product/Variant ID lists should # only contain numbers (ie. no quotes). If ':all' is used, # this can also be 'nil'. # - 'rejection_message' is the message to show when a discount # code is rejected # ================================================================ REJECT_DISCOUNT_CODE_FOR_PRODUCTS = [ { discount_code_match_type: :exact, discount_codes: ["NFT WIDGET 15%", "NFT WIDGET 20%","CIW_1667498842630"], product_selector_match_type: :include, product_selector_type: :tag, product_selectors: ["no_discount"], rejection_message: "Discount codes can't be used with 'this' products" } ] # ================================ 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.any? { |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) (@match_type == :include) == @selectors.include?(line_item.variant.id) end def subscription(line_item) !line_item.selling_plan_id.nil? end def all(line_item) true end end # ================================================================ # DisableDiscountCodesForProductsCampaign # # If any matching discount codes are used, and any matching items # are in the cart, the discount code is rejected with the entered # message. # ================================================================ class DisableDiscountCodesForProductsCampaign 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], ) next unless cart.line_items.any? { |line_item| product_selector.match?(line_item) } cart.discount_code.reject(message: campaign[:rejection_message]) end end end CAMPAIGNS = [ DisableDiscountCodesForProductsCampaign.new(REJECT_DISCOUNT_CODE_FOR_PRODUCTS), ] CAMPAIGNS.each do |campaign| campaign.run(Input.cart) end Output.cart = Input.cart
How many products du you have and how many can not have a discount?
I could have 5, 10 or whatever quantity of products, but discount have to apply considering all of them except for those that have 'no_discount' tag
I'm trying now with something like this but still not working
Input.cart.line_items.each do |line_item|
product = line_item.variant.product
next if product.gift_card?
next unless product.tags.include?('No_Discount')
discount_applicator.apply(line_item)
end
Output.cart = Input.cart
@alealdev did you happen to ever get this figured out? I am working on doing it right now and I would love to know what you learned.
Hey Community! As we jump into 2025, we want to give a big shout-out to all of you wh...
By JasonH Jan 7, 2025Hey Community! As the holiday season unfolds, we want to extend heartfelt thanks to a...
By JasonH Dec 6, 2024Dropshipping, a high-growth, $226 billion-dollar industry, remains a highly dynamic bus...
By JasonH Nov 27, 2024