Created
November 28, 2021 23:18
-
-
Save stewartknapman/b1efb34c837a8d1135178d80648fcf40 to your computer and use it in GitHub Desktop.
Shopify script to show shipping rates if products have certain tags
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ================================ Customizable Settings ================================ | |
# ================================================================ | |
# Show Rate(s) for Product Tag | |
# | |
# If we have a product with matching tag, the entered rate(s) will be | |
# shown, and all others will be hidden. Otherwise, the entered | |
# rate(s) will be hidden. | |
# | |
# - 'product_tag_match_type' determines whether we look for the | |
# product to be tagged with any of the entered tags or not. | |
# Can be: | |
# - ':include' to check if the product is tagged | |
# - ':exclude' to make sure the product isn't tagged | |
# - 'product_tags' is a list of product tags to trigger the | |
# campaign | |
# - 'rate_match_type' determines whether the below strings | |
# should be an exact or partial match. Can be: | |
# - ':exact' for an exact match | |
# - ':partial' for a partial match | |
# - 'rate_names' is a list of strings to identify rates | |
# ================================================================ | |
SHOW_RATES_FOR_PRODUCT_TAG = [ | |
{ | |
product_tag_match_type: :include, | |
product_tags: ["free_shipping"], | |
rate_match_type: :exact, | |
rate_names: ["Free Shipping"], | |
}, | |
] | |
# ================================ Script Code (do not edit) ================================ | |
# ================================================================ | |
# ProductTagSelector | |
# | |
# Finds whether the supplied product has any of the entered tags. | |
# ================================================================ | |
class ProductTagSelector | |
def initialize(match_type, tags) | |
@comparator = match_type == :include ? 'any?' : 'none?' | |
@tags = tags.map { |tag| tag.downcase.strip } | |
end | |
def match?(product_tags) | |
product_tags_cleaned = product_tags.map { |tag| tag.downcase.strip } | |
(@tags & product_tags_cleaned).send(@comparator) | |
end | |
end | |
# ================================================================ | |
# RateNameSelector | |
# | |
# Finds whether the supplied rate name matches any of the entered | |
# names. | |
# ================================================================ | |
class RateNameSelector | |
def initialize(match_type, rate_names) | |
@comparator = match_type == :exact ? '==' : 'include?' | |
@rate_names = rate_names.map { |rate_name| rate_name.downcase.strip } | |
end | |
def match?(shipping_rate) | |
@rate_names.any? { |name| shipping_rate.name.downcase.send(@comparator, name) } | |
end | |
end | |
# ================================================================ | |
# ShowRateForProductTagCampaign | |
# | |
# If we have a product with matching tags, the entered rate(s) will be | |
# shown, and all others will be hidden. Otherwise, the entered | |
# rate(s) will be hidden. | |
# ================================================================ | |
class ShowRateForProductsTagCampaign | |
def initialize(campaigns) | |
@campaigns = campaigns | |
end | |
def run(cart, shipping_rates) | |
@campaigns.each do |campaign| | |
product_tag_selector = ProductTagSelector.new( | |
campaign[:product_tag_match_type], | |
campaign[:product_tags] | |
) | |
# Get all the product tags from the line items | |
product_tags = [] | |
cart.line_items.map{|item| product_tags.concat(item.variant.product.tags) } | |
product_tags.uniq! | |
product_match = product_tag_selector.match?(product_tags) | |
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) != product_match | |
end | |
end | |
end | |
end | |
CAMPAIGNS = [ | |
ShowRateForProductsTagCampaign.new(SHOW_RATES_FOR_PRODUCT_TAG), | |
] | |
CAMPAIGNS.each do |campaign| | |
campaign.run(Input.cart, Input.shipping_rates) | |
end | |
Output.shipping_rates = Input.shipping_rates |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment