Migrating a skip already discounted items script
This looks like the easiest guard in the whole library and it is the hardest. The question it asks is about the other discounts running alongside it, not about the product, and that is a different kind of question entirely.
Shopify platform limitIt skipped any line that had already been reduced by something else.
Paste it into Scripts rescue and watch what it rebuilds
- Copy the Ruby with the button beside any Script on this page.
- In your Shopify admin, open Stackable, then Tools, then Scripts rescue.
- Paste it there, read what the tool says it will build, and compare that with the settings on this page.
Scripts rescue is on the Pro plan. Nothing is published until you tell it what your old Script charged and the two figures match to the cent.
The Script
Shopify platform limit# GENERATED BY THE SHOPIFY SCRIPT CREATOR APP
# Version 0.12.0
class Campaign
def initialize(condition, *qualifiers)
@condition = (condition.to_s + '?').to_sym
@qualifiers = PostCartAmountQualifier ? [] : [] rescue qualifiers.compact
@post_amount_qualifiers = []
@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_qualifiers << nested_q if nested_q.is_a?(PostCartAmountQualifier)
@qualifiers << qualifier
end
else
@post_amount_qualifiers << qualifier if qualifier.is_a?(PostCartAmountQualifier)
@qualifiers << qualifier
end
end if @qualifiers.empty?
end
end
class Selector
end
class ReducedItemSelector < Selector
def initialize(match_type)
@invert = match_type == :not
end
def match?(line_item)
@invert ^ line_item.discounted?
end
end
class PercentageDiscount
def initialize(percent, message)
@discount = (100 - percent) / 100.0
@message = message
end
def apply(line_item)
line_item.change_line_price(line_item.line_price * @discount, message: @message)
end
end
class ConditionalDiscount < Campaign
def initialize(condition, customer_qualifier, cart_qualifier, line_item_selector, discount, max_discounts)
super(condition, customer_qualifier, cart_qualifier)
@line_item_selector = line_item_selector
@discount = discount
@items_to_discount = max_discounts == 0 ? nil : max_discounts
end
def run(cart)
raise "Campaign requires a discount" unless @discount
return unless qualifies?(cart)
applicable_items = cart.line_items.select { |item| @line_item_selector.nil? || @line_item_selector.match?(item) }
applicable_items.each do |item|
@discount.apply(item)
end
end
end
CAMPAIGNS = [
ConditionalDiscount.new(
:all,
nil,
nil,
ReducedItemSelector.new(:not),
PercentageDiscount.new(10, "10% off full price items"),
0
),
].freeze
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cartShopify cannot do this at checkout
Your Script checked whether an item had already been discounted by something else. Discounts at checkout all run at the same moment and cannot see each other's work, so that test could only ever be half right.
This is a limit in Shopify rather than a gap in Stackable. No discount app can rebuild it today, which is why the link below goes to Shopify's own documentation and not to ours.
Read Shopify's documentationReason key: platform.perLineAlreadyDiscounted
There is no cart to test here, because nothing is built. Pasting this produces the message above and no campaign at all.
Common questions
- Will Stackable rebuild this script?
- No, and the reason is stated rather than hidden: Your Script checked whether an item had already been discounted by something else. Discounts at checkout all run at the same moment and cannot see each other's work, so that test could only ever be half right.
Related Script shapes
A discount limited to products carrying one tag, vendor or type.
Already-marked-down products protected from a second discount.
Gift cards left out of a discount that would otherwise have hit them.
Paste your Script and see it rebuilt
The rebuild is checked against the money your old Script charged before you can publish it.