All things Shopify and commerce
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
Thanks to all Community members that participated in our inaugural 2 week AMA on the new E...
By Jacqui Mar 10, 2023Upskill and stand out with the new Shopify Foundations Certification program
By SarahF_Shopify Mar 6, 2023One of the key components to running a successful online business is having clear and co...
By Ollie Mar 6, 2023