简体   繁体   English

隐藏基于产品标签的运费加倍运费

[英]Hide shipping rate based on product tag doubling shipping cost

Hi, sorry if someone has asked this before.嗨,抱歉,如果之前有人问过这个问题。 I've searched and haven't been able to find this exact problem.我已经搜索过,但没能找到这个确切的问题。 We want to charge a white glove service fee for products with the white-glove tag but keep the option for free shipping.我们想对带有白手套标签的产品收取白手套服务费,但保留免费送货的选项。 The following script works for a mixed cart (product with and without the white-glove tag), but it doubles the cost?以下脚本适用于混合购物车(带和不带白手套标签的产品),但它会使成本翻倍? I made this with a script generator so I know it's very bloated, as well.我用脚本生成器制作了它,所以我知道它也非常臃肿。

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
        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 @li_match_type.nil?
        cart.line_items.send(@li_match_type) { |item| qualifier.match?(item) }
      else
        qualifier.match?(cart, @line_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 ConditionallyHideRates < Campaign
  def initialize(condition, customer_qualifier, cart_qualifier, li_match_type, line_item_qualifier, rate_selector)
    super(condition, customer_qualifier, cart_qualifier, line_item_qualifier)
    @li_match_type = (li_match_type.to_s + '?').to_sym
    @rate_selector = rate_selector
  end
  def run(rates, cart)
    rates.delete_if { |rate| @rate_selector.match?(rate) } 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 ProductTagSelector < Selector
  def initialize(match_type, match_condition, tags)
    @match_condition = match_condition
    @invert = match_type == :does_not
    @tags = tags.map(&:downcase)
  end
  def match?(line_item)
    product_tags = line_item.variant.product.tags.to_a.map(&:downcase)
    case @match_condition
      when :match
        return @invert ^ ((@tags & product_tags).length > 0)
      else
        return @invert ^ partial_match(@match_condition, product_tags, @tags)
    end
  end
end
class RateNameSelector < Selector
  def initialize(match_type, match_condition, names)
    @match_condition = match_condition
    @invert = match_type == :does_not
    @names = names.map(&:downcase)
  end
  def match?(shipping_rate)
    name = shipping_rate.name.downcase
    case @match_condition
      when :match
        return @invert ^ @names.include?(name)
      else
        return @invert ^ partial_match(@match_condition, name, @names)
    end
  end
end
CAMPAIGNS = [
  ConditionallyHideRates.new(
    :all,
    nil,
    nil,
    :all,
    ProductTagSelector.new(
      :does_not,
      :match,
      ["white-glove"]
    ),
    RateNameSelector.new(
      :does,
      :match,
      ["White Glove"]
    )
  )
].freeze
CAMPAIGNS.each do |campaign|
  campaign.run(Input.shipping_rates, Input.cart)
end
Output.shipping_rates = Input.shipping_rates

Aside from doubling the cost, I'm sure there has to be a cleaner way to do this.除了成本翻倍之外,我确信必须有一种更清洁的方法来做到这一点。 I apologize for the formatting.我为格式道歉。 Total newbie.总新手。

I figured out the double cost-I had the service fee twice in my shipping rates?我想出了双重成本——我的运费中有两次服务费? But I'm sure there's a cleaner way to write this?但我确定有一种更简洁的方式来写这个?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM