Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ihorduchenko/e23f13849f6b40fe832430d5f0fe7b14 to your computer and use it in GitHub Desktop.
Save ihorduchenko/e23f13849f6b40fe832430d5f0fe7b14 to your computer and use it in GitHub Desktop.
Disable discount codes for the specified list of variant IDs of items
# ================================ 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: ["TEST_WAREHOUSE_SALE"],
product_selector_match_type: :include,
product_selector_type: :variant_id,
product_selectors: [8645171183724,8645171380332,31786692214849,8645172691052,31786694869057,8645174394988,31786696048705,8645174689900,8645172789356,8645174263916,8645165383788,8645165744236,31786671046721,8645165842540,31786672455745,8645166039148,31786675896385,8645166071916,8645166104684,8645166399596,30323060310081,30323061588033,32205362462785,30323062308929,32205363544129,30323066667073,32205363806273,30323070632001,30323071287361,30323073253441,8643173285996,8643173318764,31786655907905,8643173351532,31786668458049,8643173384300,31786669604929,8643173417068,8643173449836,8643173482604,29445936873537,29445944672321,31786677567553,29445946277953,31786680909889,29445950111809,31786685530177,29445953945665,29445958303809,29445959778369,31200544555073,31200544653377,39352981160119,31200544751681,39352982732983,31200544817217,39352983191735,31200544882753,31200544948289,31200545013825,31200544587841,31200544718913,39352984666295,31200544784449,39352985813175,31200544849985,39352986370231,31200544915521,31200544981057,31200545046593,39463190462647,39463268155575,39463271825591,39463307083959,39463309181111,39463310065847,39463310491831,39463311442103,39463315079351,39463316684983],
rejection_message: "Discount codes can't be used with 'discounted' 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment