Migrating a script scoped to a tag, vendor or product type
A dropped filter is the most expensive class of mistake in a migration, because it is silent and it is confident: the percentage is read perfectly and applied to everything you sell. Note that Scripts could not read collections at all.
NachgebautIt skipped every line whose product did not carry the listed tag, vendor or type.
Händler haben das auf 3 verschiedene Arten geschrieben, und sie bedeuten nicht alle dasselbe. Jede Schreibweise steht unten mit eigenem Warenkorb und eigenen Zahlen.
Fügen Sie es in die Scripts-Rettung ein und sehen Sie, was daraus wird
- Kopieren Sie das Ruby mit der Schaltfläche neben jedem Script auf dieser Seite.
- Öffnen Sie im Shopify-Adminbereich Stackable, dann Tools, dann Scripts-Rettung.
- Fügen Sie es dort ein, lesen Sie, was das Tool bauen will, und vergleichen Sie das mit den Einstellungen auf dieser Seite.
Die Scripts-Rettung gehört zum Pro-Tarif. Nichts wird veröffentlicht, bevor Sie angeben, was Ihr altes Script berechnet hat, und beide Zahlen auf den Cent genau übereinstimmen.
Official dialect, product selector include (D13)
NachgebautGefährliches Paar D13. Diese Datei und ihr Gegenstück sehen fast gleich aus und verhalten sich unterschiedlich, lesen Sie also beide, bevor Sie entscheiden, welche Sie haben.
# ================================ Customizable Settings ================================
PRODUCT_DISCOUNTS = [
{
product_selector_match_type: :include,
product_selector_type: :tag,
product_selectors: ["sale"],
discount_type: :percent,
discount_amount: 20,
discount_message: "20% off sale items",
},
]
# ================================ Script Code (do not edit) ================================
class ProductSelector
def initialize(match_type, selector_type, selectors)
@match_type = match_type
@comparator = match_type == :include ? 'any?' : 'none?'
@selector_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
def type(line_item)
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@selectors.include?(line_item.variant.product.product_type.downcase.strip)) == (@match_type == :include)
end
def vendor(line_item)
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@selectors.include?(line_item.variant.product.vendor.downcase.strip)) == (@match_type == :include)
end
def product_id(line_item)
(@selectors.include?(line_item.variant.product.id)) == (@match_type == :include)
end
def variant_id(line_item)
(@selectors.include?(line_item.variant.id)) == (@match_type == :include)
end
def all(line_item)
true
end
end
class ProductDiscountCampaign
def initialize(campaigns)
@campaigns = campaigns
end
def run(cart)
@campaigns.each do |campaign|
product_selector = ProductSelector.new(
campaign[:product_selector_match_type],
campaign[:product_selector_type],
campaign[:product_selectors],
)
cart.line_items.each do |line_item|
next unless product_selector.match?(line_item)
line_item.change_line_price(
line_item.line_price * (1 - (campaign[:discount_amount] * 0.01)),
message: campaign[:discount_message],
)
end
end
end
end
CAMPAIGNS = [
ProductDiscountCampaign.new(PRODUCT_DISCOUNTS),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cartErkannt als Percentage off und neu aufgebaut als Angebot vom Typ volume. Das sind die echten Konfigurationsschlüssel, mit denen das Angebot gespeichert wird, sodass Sie Ihren eigenen Nachbau Feld für Feld damit abgleichen können.
| Einstellung | Wert | Konfigurationsschlüssel |
|---|---|---|
| Offer type | volume | type |
| Counting | per_product | counting |
| Recurrence | once | recurrence |
| Tier 1 | min qty 1 -> 20% off | tiers[0] |
| Target scope | tags | target.scope |
| Target includes | sale | target.includeIds |
| Method | automatic | discountMethod |
| Allocation | standard | stacking.allocation |
| Combines with other discounts | no | stacking |
- Your Script limited this to a tag, vendor, or product type. We carried that filter over, so confirm it selects the products you expect.
Aufgebaut in unserem öffentlichen Demo-Shop Meridian Goods, damit sich jeder Preis hier nachrechnen lässt und nicht geglaubt werden muss. Der Rabatt unten ist das, was dieselbe Engine, die im Checkout läuft, für genau diesen Warenkorb berechnet.
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Ceramic Travel Mug | 1 | $22.00 |
| Zwischensumme | $22.00 | |
| Rabatt | -$4.40 | |
| Summe | $17.60 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Vor dem Veröffentlichen fragt das Tool, was Ihr altes Script mit einem Warenkorb gemacht hat, den Sie bereits haben. Stellen Sie ihn auf 1 von Ceramic Travel Mug zu $22.00 ein, dann steht die Antwort fest.
Der Rabatt beträgt $4.40. Der Betrag, den der Käufer gezahlt hat, ist $17.60.
Der Vergleich ist exakt, bis auf die kleinste Einheit Ihrer Währung. Ein Cent daneben und das Veröffentlichen bleibt gesperrt, genau darum geht es bei diesem Schritt.
- swap the cart for a single Braided USB-C Cable
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Braided USB-C Cable | 1 | $14.00 |
| Zwischensumme | $14.00 | |
| Summe | $14.00 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Official dialect, product selector exclude (D13)
NachgebautGefährliches Paar D13. Diese Datei und ihr Gegenstück sehen fast gleich aus und verhalten sich unterschiedlich, lesen Sie also beide, bevor Sie entscheiden, welche Sie haben.
# ================================ Customizable Settings ================================
PRODUCT_DISCOUNTS = [
{
product_selector_match_type: :exclude,
product_selector_type: :tag,
product_selectors: ["sale"],
discount_type: :percent,
discount_amount: 20,
discount_message: "20% off full-price items",
},
]
# ================================ Script Code (do not edit) ================================
class ProductSelector
def initialize(match_type, selector_type, selectors)
@match_type = match_type
@comparator = match_type == :include ? 'any?' : 'none?'
@selector_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
def all(line_item)
true
end
end
class ProductDiscountCampaign
def initialize(campaigns)
@campaigns = campaigns
end
def run(cart)
@campaigns.each do |campaign|
product_selector = ProductSelector.new(
campaign[:product_selector_match_type],
campaign[:product_selector_type],
campaign[:product_selectors],
)
cart.line_items.each do |line_item|
next unless product_selector.match?(line_item)
line_item.change_line_price(
line_item.line_price * (1 - (campaign[:discount_amount] * 0.01)),
message: campaign[:discount_message],
)
end
end
end
end
CAMPAIGNS = [
ProductDiscountCampaign.new(PRODUCT_DISCOUNTS),
]
CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end
Output.cart = Input.cartErkannt als Percentage off und neu aufgebaut als Angebot vom Typ volume. Das sind die echten Konfigurationsschlüssel, mit denen das Angebot gespeichert wird, sodass Sie Ihren eigenen Nachbau Feld für Feld damit abgleichen können.
| Einstellung | Wert | Konfigurationsschlüssel |
|---|---|---|
| Offer type | volume | type |
| Counting | per_product | counting |
| Recurrence | once | recurrence |
| Tier 1 | min qty 1 -> 20% off | tiers[0] |
| Target scope | all | target.scope |
| Target excludes | sale | target.excludeIds |
| Method | automatic | discountMethod |
| Allocation | standard | stacking.allocation |
| Combines with other discounts | no | stacking |
- Your Script limited this to a tag, vendor, or product type. We carried that filter over, so confirm it selects the products you expect.
Aufgebaut in unserem öffentlichen Demo-Shop Meridian Goods, damit sich jeder Preis hier nachrechnen lässt und nicht geglaubt werden muss. Der Rabatt unten ist das, was dieselbe Engine, die im Checkout läuft, für genau diesen Warenkorb berechnet.
- Targeting excludes sale. No Meridian Goods product carries those, so every product stays eligible and the exclusion is proved by the campaign settings, not by the cart.
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Braided USB-C Cable | 1 | $14.00 |
| Zwischensumme | $14.00 | |
| Rabatt | -$2.80 | |
| Summe | $11.20 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Vor dem Veröffentlichen fragt das Tool, was Ihr altes Script mit einem Warenkorb gemacht hat, den Sie bereits haben. Stellen Sie ihn auf 1 von Braided USB-C Cable zu $14.00 ein, dann steht die Antwort fest.
Der Rabatt beträgt $2.80. Der Betrag, den der Käufer gezahlt hat, ist $11.20.
Der Vergleich ist exakt, bis auf die kleinste Einheit Ihrer Währung. Ein Cent daneben und das Veröffentlichen bleibt gesperrt, genau darum geht es bei diesem Schritt.
- swap the cart for a single Ceramic Travel Mug
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Ceramic Travel Mug | 1 | $22.00 |
| Zwischensumme | $22.00 | |
| Summe | $22.00 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Scope targeting family tag (D9)
NachgebautGefährliches Paar D9. Diese Datei und ihr Gegenstück sehen fast gleich aus und verhalten sich unterschiedlich, lesen Sie also beide, bevor Sie entscheiden, welche Sie haben.
Input.cart.line_items.each do |li|
next unless li.variant.product.tags.include?('sale')
li.change_line_price(li.original_line_price * (1.0 - (20 / 100.0)), message: "20% off sale")
end
Output.cart = Input.cartErkannt als Percentage off und neu aufgebaut als Angebot vom Typ volume. Das sind die echten Konfigurationsschlüssel, mit denen das Angebot gespeichert wird, sodass Sie Ihren eigenen Nachbau Feld für Feld damit abgleichen können.
| Einstellung | Wert | Konfigurationsschlüssel |
|---|---|---|
| Offer type | volume | type |
| Counting | per_product | counting |
| Recurrence | once | recurrence |
| Tier 1 | min qty 1 -> 20% off | tiers[0] |
| Target scope | tags | target.scope |
| Target includes | sale | target.includeIds |
| Method | automatic | discountMethod |
| Allocation | standard | stacking.allocation |
| Combines with other discounts | no | stacking |
- Your Script limited this to a tag, vendor, or product type. We carried that filter over, so confirm it selects the products you expect.
Aufgebaut in unserem öffentlichen Demo-Shop Meridian Goods, damit sich jeder Preis hier nachrechnen lässt und nicht geglaubt werden muss. Der Rabatt unten ist das, was dieselbe Engine, die im Checkout läuft, für genau diesen Warenkorb berechnet.
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Ceramic Travel Mug | 1 | $22.00 |
| Zwischensumme | $22.00 | |
| Rabatt | -$4.40 | |
| Summe | $17.60 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Vor dem Veröffentlichen fragt das Tool, was Ihr altes Script mit einem Warenkorb gemacht hat, den Sie bereits haben. Stellen Sie ihn auf 1 von Ceramic Travel Mug zu $22.00 ein, dann steht die Antwort fest.
Der Rabatt beträgt $4.40. Der Betrag, den der Käufer gezahlt hat, ist $17.60.
Der Vergleich ist exakt, bis auf die kleinste Einheit Ihrer Währung. Ein Cent daneben und das Veröffentlichen bleibt gesperrt, genau darum geht es bei diesem Schritt.
- swap the cart for a single Braided USB-C Cable
| Artikel | Menge | Einzelpreis |
|---|---|---|
| Braided USB-C Cable | 1 | $14.00 |
| Zwischensumme | $14.00 | |
| Summe | $14.00 | |
Nicht angemeldet oder als Kunde ohne Tags angemeldet.
Zwei Dateien, die gleich aussehen
Jedes Paar unten ist dieselbe Script-Form in zwei Schreibweisen. Sie unterscheiden sich in ein, zwei Zeilen und tun Unterschiedliches. Lesen Sie beide, bevor Sie entscheiden, welche Sie haben.
Gefährliches Paar D9
Scope targeting family tag (D9)
NachgebautWird als volume-Angebot nachgebaut.
Rabatt im eigenen Warenkorb: $4.40
next unless li.variant.product.tags.include?('sale')
li.change_line_price(li.original_line_price * (1.0 - (20 / 100.0)), message: "20% off sale")Flat percentage off all (D9)
NachgebautWird als volume-Angebot nachgebaut.
Rabatt im eigenen Warenkorb: $2.80
li.change_line_price(li.original_line_price * (1.0 - (20 / 100.0)), message: "20% off everything")Gefährliches Paar D13
Official dialect, product selector include (D13)
NachgebautWird als volume-Angebot nachgebaut.
Rabatt im eigenen Warenkorb: $4.40
product_selector_match_type: :include,
discount_message: "20% off sale items",
def type(line_item)
@selectors = @selectors.map { |selector| selector.downcase.strip }
(@selectors.include?(line_item.variant.product.product_type.downcase.strip)) == (@match_type == :include)
endUnd 10 weitere abweichende Zeilen, auf der eigenen Seite.
Official dialect, product selector exclude (D13)
NachgebautWird als volume-Angebot nachgebaut.
Rabatt im eigenen Warenkorb: $2.80
product_selector_match_type: :exclude,
discount_message: "20% off full-price items",Häufige Fragen
- Will Stackable rebuild this script?
- Yes. Every spelling on this page is rebuilt today as a volume offer, and the cart above is the one that proves it.
- What cart proves it works?
- 1 x Ceramic Travel Mug at $22.00. The engine takes $4.40 off, and checkout charges $17.60.
- What will I have to check before publishing?
- Your Script limited this to a tag, vendor, or product type. We carried that filter over, so confirm it selects the products you expect.
Verwandte Script-Formen
One percentage off the whole catalogue, with no condition attached.
Already-marked-down products protected from a second discount.
Gift cards left out of a discount that would otherwise have hit them.
Fügen Sie Ihr Script ein und sehen Sie den Nachbau
Der Nachbau wird mit dem Betrag abgeglichen, den Ihr altes Script berechnet hat, bevor Sie ihn veröffentlichen können.