New Shopify Certification now available: Liquid Storefronts for Theme Developers

Create a conditional for products containing certain tags

7 0 1


I have a Bundle Discount script (created with the Script Creator) where customers get % off when buying a combination of certain products (pid). In the BundleDiscount object there are bundle_products which form the bundle. I then have the CAMPAIGNS array that contains all the bundle instances. 
The way the script works is it first applies the discount on the BundleDiscount object that has the lowest index in the CAMPAIGNS array (the first object in the array). So that becomes a problem when users are on a particular bundle page that contains several products forming a discount (let's call it Bundle 1). Once added to the cart, they get the discount as Bundle 1, however, if you add other single products to the cart later on that are also part of a pack (Bundle 2), they might break the first bundle if one of the products is in both bundles, and if Bundle 2 is mentioned before Bundle 1 in the array (because the products will regroup accordingly):
   Bundle 2,

   Bundle 1
This is a no-go, because if users picked the products from a Bundle page, they would want to keep them grouped as they check out.
So how i want to solve it is creating tags only for the bundle product pages, then If a user is on product pages that contain those tags, I want to push the BundleDiscount object that contains these products in the beginning of the CAMPAIGNS array, meaning that this will be the first bundle to get the discount.
I've been trying for a week now, but I am completely clueless on how to approach this problem in Ruby..

Some of the code:

class Campaign
  def initialize(condition, *qualifiers)
    @condition = (condition.to_s + '?').to_sym
    @qualifiers = PostCartAmountQualifier ? [] : [] rescue qualifiers.compact
    @line_item_selector = qualifiers.last unless @line_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
        @post_amount_qualifier = qualifier if qualifier.is_a?(PostCartAmountQualifier)
        @qualifiers << qualifier
    end if @qualifiers.empty?

  def qualifies?(cart)
    return true if @qualifiers.empty?
    @unmodified_line_items = 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 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 @li_match_type.nil?
        cart.line_items.send(@li_match_type) { |item| qualifier.match?(item) }
        qualifier.match?(cart, @line_item_selector)

  def run_with_hooks(cart)
    before_run(cart) if respond_to?(:before_run)

  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)

class BundleDiscount < Campaign
  def initialize(condition, customer_qualifier, cart_qualifier, discount, full_bundles_only, bundle_products)
    super(condition, customer_qualifier, cart_qualifier, nil)
    @bundle_products = bundle_products
    @discount = discount
    @full_bundles_only = full_bundles_only
    @split_items = []
    @bundle_items = []
def check_bundles(cart) bundled_items = do |bitem| quantity_required = bitem[:quantity].to_i qualifiers = bitem[:qualifiers] type = bitem[:type].to_sym case type when :pid!(&:to_i) items = { |item| qualifiers.include?( && !item.discounted? } end total_quantity = items.reduce(0) { |total, item| total + item.quantity } { has_all: total_quantity >= quantity_required, total_quantity: total_quantity, quantity_required: quantity_required, total_possible: (total_quantity / quantity_required).to_i, items: items } end false end def split_out_extra_quantity(cart, items, total_quantity, quantity_required) #some (irrelevant for now) code that split out extra quantity out of a pack end class PercentageDiscount def initialize(percent, message) @discount = (100 - percent) / 100.0 @message = message end def apply(line_item) line_item.change_line_price(line_item.line_price * @discount, message: @message) end end CAMPAIGNS = [ # Single bundle :any, nil, nil, 12.01, "Bundle discount applied" ), true, [ {:type => "pid", :qualifiers => ["2631126679652"], :quantity => "1"}, {:type => "pid", :qualifiers => ["2631131365476"], :quantity => "1"} ] ) ].freeze CAMPAIGNS.each do |campaign| campaign.run_with_hooks(Input.cart) end Output.cart = Input.cart



Replies 0 (0)