Migrating a discounted cart subtotal script
Two scripts can look identical here and mean opposite things. One measures what its own earlier lines left behind; the other measures what somebody else’s discount left behind, and only the second is out of anyone’s hands.
Shopify の制限It subtracted the shopper’s discount code from the subtotal first, then compared what was left against its threshold.
スクリプトレスキューに貼り付けて、何が再現されるか確認する
- このページの各スクリプトの横にあるボタンで Ruby をコピーします。
- Shopify 管理画面で Stackable を開き、ツール、スクリプトレスキューの順に進みます。
- そこに貼り付け、ツールが作成すると示した内容を読み、このページの設定と見比べます。
スクリプトレスキューは Pro プランの機能です。以前のスクリプトの割引額を入力し、両方の金額が最小通貨単位まで一致するまで、何も公開されません。
Script 本体
Shopify の制限# GENERATED BY THE SHOPIFY SCRIPT CREATOR APP
# Version 0.12.0
class Qualifier
def compare_amounts(compare, comparison_type, compare_to)
case comparison_type
when :greater_than
return compare > compare_to
when :greater_than_or_equal
return compare >= compare_to
else
raise "Invalid comparison type"
end
end
end
class PostCartAmountQualifier < Qualifier
def initialize(comparison_type, amount)
@comparison_type = comparison_type
@amount = Money.new(cents: amount * 100)
end
def match?(cart, selector = nil)
total = cart.subtotal_price
compare_amounts(total, @comparison_type, @amount)
end
end
class PostCartAmountIncDiscCodeQualifier < PostCartAmountQualifier
def initialize(comparison_type, amount)
super(comparison_type, amount)
end
def match?(cart, selector = nil)
total =
case cart.discount_code
when CartDiscount::Percentage
if cart.subtotal_price >= cart.discount_code.minimum_order_amount
cart_subtotal_without_gc = cart.line_items.reduce(Money.zero) do |total, item|
total + (item.variant.product.gift_card? ? Money.zero : item.line_price)
end
gift_card_amount = cart.subtotal_price - cart_subtotal_without_gc
cart_subtotal_without_gc * ((Decimal.new(100) - cart.discount_code.percentage) / 100) + gift_card_amount
else
cart.subtotal_price
end
when CartDiscount::FixedAmount
if cart.subtotal_price >= cart.discount_code.minimum_order_amount
[cart.subtotal_price - cart.discount_code.amount, Money.zero].max
else
cart.subtotal_price
end
else
cart.subtotal_price
end
compare_amounts(total, @comparison_type, @amount)
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)
cart.line_items.each do |item|
@discount.apply(item)
end
end
end
CAMPAIGNS = [
ConditionalDiscount.new(
:all,
nil,
PostCartAmountIncDiscCodeQualifier.new(:greater_than_or_equal, 100),
nil,
PercentageDiscount.new(5, "5% off orders over $100 after discounts"),
0
),
].freeze
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cartShopify cannot do this at checkout
Your Script measured its threshold against a subtotal that another discount had already reduced. Discounts at checkout all run at the same moment and cannot see each other's work, so we only ever see the original amounts.
これは Stackable の不足ではなく Shopify 側の制限です。現時点ではどの割引アプリでも再現できません。そのため下のリンクは当社ではなく Shopify のドキュメントに向いています。
Shopify のドキュメントを読む理由キー: platform.postDiscountSubtotal
何も作成されないため、ここに検証できるカートはありません。これを貼り付けても上のメッセージが出るだけで、キャンペーンは作成されません。
よくある質問
- Will Stackable rebuild this script?
- No, and the reason is stated rather than hidden: Your Script measured its threshold against a subtotal that another discount had already reduced. Discounts at checkout all run at the same moment and cannot see each other's work, so we only ever see the original amounts.
関連する Script の型
A percentage that unlocks once the cart is worth enough.
A flat sum off the order once the cart crosses a value.