Hi Developer,
Recently I am working on the discount code which can offer various offers based on the product tags i.e.
Let’s say discount code is ‘VIPDISCOUNT’ and in the checkout page it should offer the discount offer based on the product tags for example:
if the product tags contains 30% then give 30% off, if product tag contains 40% then it should give 40% off.
Below is the code sample in the script editor, As you can see it gives 10% off based on the ‘discount_amount: 10’; is there any way i can mutate(pass the value) the discount_amount value based on the product tags i.e. if line_item.variant.product.tags.include? ‘30%’ discount_amout: 30 elsif line_item.variant.product.tags.include? ‘40%’ discount_amount: 40
PRODUCT_DISCOUNTS_BY_DISCOUNT_CODE = [
{
discount_code_match_type: :exact,
discount_codes: ["TESTCODE1", "VIPDISCOUNT"],
product_selector_match_type: :include,
product_selector_type: :tag,
product_selectors: ["VIPSALE"],
discount_type: :percent,
discount_amount: 10,
discount_message: '10% off tagged products!'
}
]
# 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
# 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
# ================================================================
# 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
Money.new(cents: 100) * 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 * line_item.quantity), 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 items
# 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
Output.cart = Input.cart
I would really appreciate your time and information