Hi all,
I am fairly new to Shopify scripts and I was able to create 2 scripts that help me solve my problem. But as I was publishing them, I just found out I can’t have multiple scripts running at once for the same type, so I would love to get someone’s help with this.
Some of my products are tagged with “status-special-order” and require 10-15 business days to ship, while all other items are in stock and available to ship within 1 business day.
When a user adds both stocked item(s) AND special order items, I want to show these (2) specific shipping rates so the user can pick one of these options:
-
Free Shipping: I’m in a rush. Send me stocked item(s) now, and special item(s) when available.
-
Free Shipping: I’m in no rush. I can wait for all items to be available and help offset carbon footprint.
I was able to tweak an existing Shopify script so I would see these options, and it would hide all of my other custom and carrier shipping rates whenever a special order item is in the cart. However I would like to hide these (2) shipping rates (listed above) when there is no special order item in the cart.
I wish I could just add another condition somewhere saying that if the product tag “status-special-order” is not included, then it should hide the (2) custom shipping rates I listed higher in my message.
Any help would be very much appreciated!
Thank you!
HIDE_RATES_FOR_PRODUCT = [
{
product_selector_match_type: :include,
product_selector_type: :tag,
product_selectors: ["status-special-order"],
rate_match_type: :exact,
rate_names: ["Free Shipping (Regular)","$5.99 Flat Rate","Expedited Parcel","Xpresspost
","Priority"],
},
]
# ================================================================
# 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?'
_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
end
# ================================================================
# RateNameSelector
# Finds whether the supplied rate names match any of the entered names.
# ================================================================
class RateNameSelector
def initialize(match_type, rate_names)
@match_type = match_type
@comparator = match_type == :exact ? '==' : 'include?'
@rate_names = rate_names&.map { |rate_name| rate_name.downcase.strip }
end
def match?(shipping_rate)
if @match_type == :all
true
else
@rate_names.any? { |name| shipping_rate.name.downcase.send(@comparator, name) }
end
end
end
# ================================================================
# HideRatesForProduct
# If the cart contains any matching items, the entered rate(s) are hidden.
# ================================================================
class HideRatesForProduct
def initialize(campaigns)
@campaigns = campaigns
end
def run(cart, shipping_rates)
address = cart.shipping_address
return if address.nil?
@campaigns.each do |campaign|
product_selector = ProductSelector.new(
campaign[:product_selector_match_type],
campaign[:product_selector_type],
campaign[:product_selectors],
)
product_match = cart.line_items.any? { |line_item| product_selector.match?(line_item) }
next unless product_match
rate_name_selector = RateNameSelector.new(
campaign[:rate_match_type],
campaign[:rate_names],
)
shipping_rates.delete_if do |shipping_rate|
rate_name_selector.match?(shipping_rate)
end
end
end
end
CAMPAIGNS = [
HideRatesForProduct.new(HIDE_RATES_FOR_PRODUCT),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart, Input.shipping_rates)
end
Output.shipping_rates = Input.shipping_rates


