Exclude product variants from all discount codes

rockjuice2
Visitor
3 0 0

I want to use a script to exclude any coupon from being used on specific product variants(not collections or full products)

 

Context

We have many coupon codes with affiliates as well as 1 time use codes that go out for email subscribers and SMS etc. So we have hundreds of coupon codes out there. We have always excluded preset bundles from coupon codes using the collection method.  We have since added multi-pack variants to each of our individdual products that have a hard discount. The price of the 3pack is already discounted so we don't want customers double-dipping with coupon codes.

 

There are two scripts on this link. One titled "Disable discount codes" this disables all codes from being used. You typically use this when running a store-wide sale so nobody can double dip. The other script is "Disable discount codes for product" this one allows you to input specific discount codes for specific products or product variants.

 

I'm trying to merge the two. I would like to have ALL coupon codes disabled for specific product variants all the time so that I don't have to input every unique coupon code that could be used into the script. I would also have to update it with additional codes constantly. I know that I will have to enter the unique SKU of each variant I want it to apply to.  

 

Any help would be appreciated. Thank you in advance.

Replies 11 (11)

playwright-mike
Shopify Partner
72 18 33

Hey there, I've generated this script for you. It blocks all discount codes for the listed variant IDs and displays a message to the customer. You can further customize it toward the bottom. I'll also attach it as a .txt file just in case.

 

 

########################################################################
##  Create Shopify scripts without writing code at playwrightapp.com  ##
########################################################################
class Campaign
  def initialize(condition, *qualifiers)
    @condition = (condition.to_s + '?').to_sym
    @qualifiers = PostCartAmountQualifier ? [] : [] rescue qualifiers.compact
    _item_selector = qualifiers.last unless _item_selector
    qualifiers.compact.each do |qualifier|
      is_multi_select = qualifier.instance_variable_get(:@conditions).is_a?(Array)
      if is_multi_select
        qualifier.instance_variable_get(:@conditions).each do |nested_q|
          @post_amount_qualifier = nested_q if nested_q.is_a?(PostCartAmountQualifier)
          @qualifiers << qualifier
        end
      else
        @post_amount_qualifier = qualifier if qualifier.is_a?(PostCartAmountQualifier)
        @qualifiers << qualifier
      end
    end if @qualifiers.empty?
  end

  def qualifies?(cart)
    return true if @qualifiers.empty?
    @unmodified_line_items = cart.line_items.map do |item|
      new_item = item.dup
      new_item.instance_variables.each do |var|
        val = item.instance_variable_get(var)
        new_item.instance_variable_set(var, val.dup) if val.respond_to?(:dup)
      end
      new_item
    end if @post_amount_qualifier
    @qualifiers.send(@condition) do |qualifier|
      is_selector = false
      if qualifier.is_a?(Selector) || qualifier.instance_variable_get(:@conditions).any? { |q| q.is_a?(Selector) }
        is_selector = true
      end rescue nil
      if is_selector
        raise "Missing line item match type" if _match_type.nil?
        cart.line_items.send(@li_match_type) { |item| qualifier.match?(item) }
      else
        qualifier.match?(cart, _item_selector)
      end
    end
  end

  def run_with_hooks(cart)
    before_run(cart) if respond_to?(:before_run)
    run(cart)
    after_run(cart)
  end

  def after_run(cart)
    @discount.apply_final_discount if @discount && @discount.respond_to?(:apply_final_discount)
    revert_changes(cart) unless @post_amount_qualifier.nil? || @post_amount_qualifier.match?(cart)
  end

  def revert_changes(cart)
    cart.instance_variable_set(:@line_items, @unmodified_line_items)
  end
end

class ConditionalDiscountCodeRejection < Campaign
  def initialize(condition, customer_qualifier, cart_qualifier, li_match_type, line_item_qualifier, message)
    super(condition, customer_qualifier, cart_qualifier, line_item_qualifier)
    _match_type = (li_match_type.to_s + '?').to_sym
    @message = message == "" ? "This discount code cannot be used at this time" : message
  end

  def run(cart)
    return unless cart.discount_code
    cart.discount_code.reject({message: @message}) if qualifies?(cart)
  end
end

class Selector
  def partial_match(match_type, item_info, possible_matches)
    match_type = (match_type.to_s + '?').to_sym
    if item_info.kind_of?(Array)
      possible_matches.any? do |possibility|
        item_info.any? do |search|
          search.send(match_type, possibility)
        end
      end
    else
      possible_matches.any? do |possibility|
        item_info.send(match_type, possibility)
      end
    end
  end
end

class VariantIdSelector < Selector
  def initialize(match_type, variant_ids)
    @invert = match_type == :not_one
    @variant_ids = variant_ids.map { |id| id.to_i }
  end

  def match?(line_item)
    @invert ^ @variant_ids.include?(line_item.variant.id)
  end
end

CAMPAIGNS = [
  ConditionalDiscountCodeRejection.new(
    :all,
    nil,
    nil,
    :any,
    VariantIdSelector.new(
      :is_one,
      ["0123456789", "9876543210"]
    ),
    "Sorry, cannot use discount codes with this purchase"
  )
].freeze

CAMPAIGNS.each do |campaign|
  campaign.run_with_hooks(Input.cart)
end

Output.cart = Input.cart

 

 

Feel free to test it out and let me know if you need any changes!

 

Best,

Matthew

Playwright | Create Shopify Scripts without writing code | https://playwrightapp.com
- Was my reply helpful? Please Like and Accept Solution.

rockjuice2
Visitor
3 0 0

@playwright-mike 

 

Thank you so much. I will give it a go. Will this allow discounts to be applied to the other products? If we exclude 3 packs from any discount code and someone buys a 3 pack and a single would the discount codes still apply to the singles that are in the cart with the 3 pack?

playwright-mike
Shopify Partner
72 18 33

@rockjuice2, no. This script will simply reject any and all discount codes when those products are in the cart. 

If you find you need to switch strategies, let me know!

Playwright | Create Shopify Scripts without writing code | https://playwrightapp.com
- Was my reply helpful? Please Like and Accept Solution.

rockjuice2
Visitor
3 0 0

@playwright-mike  We will have people buying packs as well as individual items. Is there a way to write the script where it would allow the discount to be used on the individual items and just not the 3 packs?

 

Hypothetically the cart would have:

3 pack $20

Single $10

Single $10

Subtotal $40

 

20% off Coupon code xxx

 

3pack would stay at $20

Single 1 drops to $8

Single 2 drops t0 $8

New Subtotal $36

Derek_Morin
Shopify Expert
216 1 34

@rockjuice2 Here's a video I recorded for you, using this app.

 

LionEnergy
Tourist
10 2 1

Hi Playwright-Matt:

I have a very similar issue. We want to disable all discount codes on specific product items or variants, but we want all other products to accept the discount codes.

We have a lot of affiliate marketers that sign up to be an affiliate automatically, and so we have dozens of dynamic discount codes.

 

It is easier to take a product and just say "make this product unavailable for discount", but allow any other product in the cart to be able to use the code.

 

I have been using Playwright Script Generator to try to do this, but I can only see a way to disable all discount codes if one of those specific products is in the cart.

 

Is there a way to do this? 

busyronin
Tourist
5 0 0

Hey Matthew! I can't figure out which part of your script I should edit to have it exclude my variants "solid gold" which have the tag "solid gold" and also in the SKU have text 14k-solid-yellow-gold or 14k-solid-white-gold (but all are tagged the same as solid gold). Thank you!

playwright-mike
Shopify Partner
72 18 33

Hey @busyronin, responded to you in a private message.

Playwright | Create Shopify Scripts without writing code | https://playwrightapp.com
- Was my reply helpful? Please Like and Accept Solution.

jane33
Visitor
1 0 0

Hi there, 

 

I am trying to block ALL active discount codes that exist from affiliate's and automatic codes from newsletters on a certain SKU. We lowered the price of a product because it's out of stock. We are offering the lower price to pre order. We don't want customers to be able to apply additional discounts to that product. If they do have an discount code it can work on other SKUS just want to exclude a specific product.

 

I reached out to the app mentioned above "Automatic discount." waiting to hear back. If anyone has any advice on how to do this, please let me know. Thank you! 

MrBrady
Shopify Partner
6 0 0

This works great for my needs of excluding discount codes from applying to certain variants. Thank you!

serihon
Shopify Partner
3 0 0

Where would this script be utilized?