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.
Starting a B2B store is a big undertaking that requires careful planning and execution. W...
By JasonH Sep 23, 2024By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024