Hi there,
I am currently running a script that hides shipping sources & names based products in the cart.
I currently have (3) scenarios:
- if all items in cart contain the product tag “status-special-order”, then it hides some of my shipping options.
- if any of the items in the cart contain the product tag “status-special-order”, then it hides some of my shipping options.
- if none of the items in the cart contain the product tag “status-special-order”, then it hides some of my shipping options.
This script is working perfectly fine but I can’t seem to make it work when trying to add an extra loop to check the province_code.
I would need to include a condition so that if province_code = [“BC”,“AB”,“ON”,“SK”,“MB”,“NB”,“NS”,“PE”,“QC”] then it runs the script below, but if province_code does not match any of these codes, then it only shows (2) shipping options. I can’t seem to make it work, and any help would be much appreciated ![]()
Thank you so much!
HIDE_RATES_FOR_ONLY_SPECIAL_ORDER = [
{
product_selector_match_type: :include,
product_selector_match_scope: :all,
product_selector_type: :tag,
product_selectors: ["status-special-order"],
rate_match_type: :exact,
rate_names: ["Free Shipping ($35 min.)","$5.99 Flat Rate","Expedited Parcel","Xpresspost","Priority","Send me the stocked item(s) now and the special item(s) when available.","I can wait for all items to be available and help offset carbon footprint."],
},
]
HIDE_RATES_FOR_MIXED_ORDER = [
{
product_selector_match_type: :include,
product_selector_match_scope: :any,
product_selector_type: :tag,
product_selectors: ["status-special-order"],
rate_match_type: :exact,
rate_names: ["Free Shipping ($35 min.)","$5.99 Flat Rate","Expedited Parcel","Xpresspost","Priority","Send me the special order item(s) when available."],
},
]
HIDE_RATES_FOR_STOCK_ORDER = [
{
product_selector_match_type: :exclude,
product_selector_match_scope: :any,
product_selector_type: :tag,
product_selectors: ["status-special-order"],
rate_match_type: :exact,
rate_names: ["Send me the stocked item(s) now and the special item(s) when available.","I can wait for all items to be available and help offset carbon footprint.","Send me the special order item(s) when available."],
},
]
# ================================================================
# 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
campaign_satisified = false
return if address.nil?
@campaigns.each do |campaign|
product_selector = ProductSelector.new(
campaign[:product_selector_match_type],
campaign[:product_selector_type],
campaign[:product_selectors],
)
if campaign[:product_selector_match_scope] == :all
product_match = cart.line_items.all? { |line_item| product_selector.match?(line_item) }
else
product_match = cart.line_items.any? { |line_item| product_selector.match?(line_item) }
end
next unless product_match
rate_name_selector = RateNameSelector.new(
campaign[:rate_match_type],
campaign[:rate_names],
)
shipping_rates.each do |shipping_rate|
if rate_name_selector.match?(shipping_rate)
campaign_satisified = true
end
end
shipping_rates.delete_if do |shipping_rate|
rate_name_selector.match?(shipping_rate)
end
end
return campaign_satisified
end
end
CAMPAIGNS = [
HideRatesForProduct.new(HIDE_RATES_FOR_ONLY_SPECIAL_ORDER),
HideRatesForProduct.new(HIDE_RATES_FOR_MIXED_ORDER),
HideRatesForProduct.new(HIDE_RATES_FOR_STOCK_ORDER)
]
CAMPAIGNS.each do |campaign|
break if campaign.run(Input.cart, Input.shipping_rates)
end
Output.shipping_rates = Input.shipping_rates
