Have your say in Community Polls: What was/is your greatest motivation to start your own business?

Update script to give free shipping based on customer tag and shipping address country

Update script to give free shipping based on customer tag and shipping address country

lana-mukti
Tourist
5 0 1

We currently have a script that runs to offer free shipping based on different customer tags, but we also want to restrict this to customers in Australia.

 

Our current script is as below and we're struggling to add in country parameters:

 

 

 

LVL2 = "swell_vip_level 2"
LVL3 = "swell_vip_level 3"
SUB = "tier: Subscriber"
MSG2 = "Free Standard Shipping"
MSG3 = "Free Express Shipping"
TYPE = "SAMPLE"
STD = "STANDARD"
EXP = "EXPRESS"
SMP = "SAMPLES"

customer = Input.cart.customer

if customer
if customer.tags.include?(LVL2)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?("Standard")
shipping_rate.change_name("Free Standard Shipping", { message: "Free Standard Shipping" })
shipping_rate.apply_discount(shipping_rate.price, message: MSG2)
end
end
end
if customer.tags.include?(LVL3)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?("Express")
shipping_rate.change_name("Free Express Shipping", { message: "Free Express Shipping" })
shipping_rate.apply_discount(shipping_rate.price, message: MSG3)
end
end
end
if customer.tags.include?(LVL3)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?("Standard")
shipping_rate.change_name("Free Standard Shipping", { message: "Free Standard Shipping" })
shipping_rate.apply_discount(shipping_rate.price, message: MSG2)
end
end
end
if customer.tags.include?(SUB)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?("Express")
shipping_rate.change_name("Free Express Shipping", { message: "Free Express Shipping" })
shipping_rate.apply_discount(shipping_rate.price, message: MSG3)
end
end
end
end

Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
if Input.cart.line_items.all? { |li| li.variant.product.product_type.upcase.include?(TYPE) }
shipping_rate.name.upcase.start_with?(STD) || shipping_rate.name.upcase.start_with?(EXP)
else
shipping_rate.name.upcase.start_with?(SMP)
end
end


# ================================ Customizable Settings ================================
# ================================================================
# Discount Rate(s) by Discount Code(s)
#
# If one of the entered discount codes is used, the entered
# rate(s) are discounted by the entered amount.
#
# - 'discount_code_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
# - 'discount_codes' is a list of strings to identify discount
# codes
# - '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
# - 'discount_type' is the type of discount to provide. Can be
# either:
# - ':percent'
# - ':dollar'
# - 'discount_amount' is the percentage/dollar discount to
# apply
# - 'discount_message' is the message to show when a discount
# is applied
# ================================================================
DISCOUNTS_FOR_DISCOUNT_CODES = [
{
discount_code_match_type: :exact,
discount_codes: ["VITAMINA-TRIAL", "ADN-TRIAL", "BLEMISH-TRIAL"],
rate_match_type: :exact,
rate_names: ["Standard", "Shipping Rate", "Other Shipping Rate"],
discount_type: :percent,
discount_amount: 100,
discount_message: "Free Shipping with discount code"
},
]

# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountCodeSelector
#
# Finds whether the supplied discount code matches any of the
# entered codes.
# ================================================================
class DiscountCodeSelector
def initialize(match_type, discount_codes)
@comparator = match_type == :exact ? '==' : 'include?'
@discount_codes = discount_codes.map { |discount_code| discount_code.upcase.strip }
end

def match?(discount_code)
@discount_codes.any? { |code| discount_code.code.upcase.send(@comparator, code) }
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

# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied shipping rate.
# ================================================================
class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)
@discount_type = discount_type
@discount_message = discount_message

@discount_amount = if discount_type == :percent
discount_amount * 0.01
else
Money.new(cents: 100) * discount_amount
end
end

def apply(shipping_rate)
rate_discount = if @discount_type == :percent
shipping_rate.price * @discount_amount
else
@discount_amount
end

shipping_rate.apply_discount(rate_discount, message: @discount_message)
end
end

# ================================================================
# DiscountRatesForDiscountCodeCampaign
#
# If one of the entered discount codes is used, the entered
# rate(s) are discounted by the entered amount.
# ================================================================
class DiscountRatesForDiscountCodeCampaign
def initialize(campaigns)
@campaigns = campaigns
end

def run(cart, shipping_rates)
return if cart.discount_code.nil?

@campaigns.each do |campaign|
discount_code_selector = DiscountCodeSelector.new(campaign[:discount_code_match_type], campaign[:discount_codes])

next unless discount_code_selector.match?(cart.discount_code)

rate_name_selector = RateNameSelector.new(campaign[:rate_match_type], campaign[:rate_names])
discount_applicator = DiscountApplicator.new(
campaign[:discount_type],
campaign[:discount_amount],
campaign[:discount_message],
)

shipping_rates.each do |shipping_rate|
next unless rate_name_selector.match?(shipping_rate)
discount_applicator.apply(shipping_rate)
end
end
end
end

CAMPAIGNS = [
DiscountRatesForDiscountCodeCampaign.new(DISCOUNTS_FOR_DISCOUNT_CODES),
]

CAMPAIGNS.each do |campaign|
campaign.run(Input.cart, Input.shipping_rates)
end

Output.shipping_rates = Input.shipping_rates

Replies 3 (3)

PaulMartin
Shopify Partner
615 59 145

This looks like Ruby code, you might want to contact whoever wrote this as they have more knowledge of this ruby code than anyone else here in the community. But if you are up for it, you can contact me for help.

contact@paulmartinlopez.com
Feel free to email me! 😄
I'm open to conversations or work ʕ •ᴥ•ʔ

stefansweb2020
Shopify Partner
134 10 5

If you are Shopify Plus client and using script editor you will need a ruby developer to help you with that, feel free to connect

banned

RMedia
Shopify Partner
93 9 11

@lana-mukti 
You can easily create free shipping based on different customer tags + country using Advanced Free Shipping.
The app uses Shopify's new shipping discount API, and lets you create shipping discounts with many different scenarios and checkout choices.
Also, with Shopify deprecating 'Scripts' in the near future, this is the ideal (and easy) solution.
Let me know if I can help further!

Founder @ Advanced Free Shipping, create custom free shipping rules easily.
- Set Free-Shipping by 20 parameters; products, collections, customers + more
- No need for confusing Scripts or Carrier Calculated Shipping
- To learn more about 'Advanced Free Shipping' visit our Shopify app page here.