Giter Club home page Giter Club logo

shopify-script-creator's People

Contributors

bradmurchison avatar charlyhue avatar dependabot[bot] avatar ewan-jrpets avatar jgodson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shopify-script-creator's Issues

Will there be a version of this for Shopify Functions?

Since Script Editor is being discontinued, will there be a tool to write Shopify Functions that works similar to your Script Creator app? I don't write in Ruby, so the Script Creator has been a life saver for writing advanced scripts. I am hoping to see something like this for Functions.

Tier pricing to a certain quantity and back to normal price.

Hello!

I'm looking on the tiered discount campaign.

My current tier discount is:-

BUY 1 FOR $50 ( SINGLE PACK )
BUY 2 FOR $90 ( 10% OFF ) ( DUO PACK )
BUY 3 FOR $126 ( 16% OFF ) ( TRIO PACK )

on the 4th item, i noticed the tiered discount would pick up on the tier 3 discount ( which is the 16% off ).. is it possible to make the 4th item to be on a normal price? ( TRIO + SINGLE ), and on the 5th item, ( TRIO + DUO )?

Screenshot 2022-05-23 at 1 29 24 PM

Bug: VariantSkuSelector RuntimeError when some line items don't have SKUs (undefined method 'downcase' for nil)

Hi there

Thanks for maintaining such a great tool. We use it a lot.

I came across this error today which was preventing a Black Friday campaign from running properly.

The issue is that if you have configured a variant selector based on SKU in Script Creator, then a RuntimeError is thrown if any of the cart line items do not have a SKU set on them.

The RuntimeError message is undefined method 'downcase' for nil.

See below screenshot:

image

Related source file lines:

Hopefully this is a relatively simple fix!

Discount on payment methods

Hi

Need to create a script of Discount when payment method selected to increase prepayment encouragement. When the user selects a credit card instead of COD, some percentage discount to that customer.

You done a great job can work in it.

Line Item title

I have been using the below very basic script to apply a discount based on the line_item.variant.title. I would now like to introduce a qualifier based on a customer tag, and so, I am here trying to generate this script. I can't sort out how to use the generator to reference the variant title. DISCOUNTED ITEM SELECTOR = Has Properties "Keys and values" seems to be the right place, but I don't think code is present to expose and reference the variant details for this to work... unless I am doing something wrong?

Input.cart.line_items.each do |line_item|
product = line_item.variant.product
next if product.gift_card?
next unless line_item.variant.title == 'Size 4 Mens'
line_item.change_line_price(line_item.line_price * 0.80, message: "DISCOUNT APPLIED")
end

Output.cart = Input.cart

Feature request: export/import via textarea input

Hi there! Thanks for creating this script generator, it has been amazing to use.

Just for convenience's sake, would it be possible to view the exported script code in a textarea when it is exported and have option to download file? And for importing, it would be great to accept the value of a textarea, as well as being able to upload a file.

Feature Request: Cart Qualifier for total before discounts

We offer free shipping at $40. For customers tagged with VIP, we'd like to offer that regardless of whether they use a discount code or not.

We have shipping options by cost or weight.
A shipping rate is calculated by weight, unless the order is $40 or more, then it's free.

For our to customers, they'll have a subtotal of $45, but use a code that drops that down to $38. I want them to sell get free shipping.

Sort Campagins

It is not an issue, some requests...

  1. Ability to order the campaigns. When creating a script with multiple campaigns, sometimes I don't create them necessarily in the order I want them to run (last minute changes, etc.) - the order can be important since one campaign might affect another,.

  2. Is it possible to add a "add to script generation (or something like that)" checkbox in each Campaign so only those selected will included in the generated script? This would allow us to use the tool to create and manage multiple types of campaigns and just generate scripts with those we need for a specific promo.

Thanks so much - and very good work. I use this in combination with a liquid snippet in the theme to display the promos/free gifts popups and works very well.

Bundle Discounts

Hi Jason,

I'm having a problem with the bundle discount. When it runs by itself (it is the only campaign) it runs, however when is combined with another, it does not apply the discounts.

I have the script configured to do this:

  1. 5% for customer tag Member (this always runs)
  2. Bundle - buy a table and a paddle and get an additional 5% off

If it runs first, then it applies the discounts - if it runs after any other campaign, then it doesn't - and it does not use the discounted item selector (discount by script) - so it should work, I think

Thanks!

Line item Buy X Get X Discounted

I have created a Buy X Get X Discounted campaign where the customer must buy 10 items to get 10 items. The maximum sets is 2. My understanding would be that this discount would only apply when the customer has 10 or 20 items. However, if the customer has 11 items the discount is applied to all items. I would expect the discount to only be applied to 10 items until the next set of items have been met, which would be 20.

Is my understanding correct?

If so, then the following adjustment would make sense within class BuyXGetX < Campaign

discountable_quantity = (discountable_sets * @get_x).to_i
discountable_quantity = purchased_quantity - (discountable_sets % @get_x).to_i

When the cart has 11 qualifying items this will split the line so that 10 items are discounted and 1 item is full price. When the cart has 21 qualifying items this will split the line so that 20 items are discounted and 1 item is full price and so on.

Apply discount using line item's Compare At Price

We absolutely love this app, thank you so much for making scripting easy for small businesses like mine!

I have a feature request, or if someone can please advise:

How do we apply a discount using the line item's Compare At Price? We'd like to be able apply a 40% MSRP discount to all line items in a cart if a customer is tagged "VIPTAG"

I found this code which works in Shopify Scripts as-is, but can't figure out where to insert it so that it works with the rest of my desired qualifiers like the tagging function. I have a feeling this a probably a popular request, so please let me know if I'm just missing something in the existing dropdowns.

Input.cart.line_items.each do |line_item|
  compare_at_price = line_item.variant.compare_at_price
  new_line_price = compare_at_price - (compare_at_price * (Decimal.new(0.75) / 100.0))

  if new_line_price < line_item.line_price
    line_item.change_line_price(new_line_price, message: '75% off original price')
  end
end

Output.cart = Input.cart

Feature Request: Recognize Selling Plans

Would love to see a cart qualifier for if there are subscription items in the cart or not. Taken a step further, only applying discounts to one-time or subscription versions of specific product/variant.

Your script exceeded the cpu limit.

Hello,

Recently I've tried to use some scripts generated by your script creator in a sale event, and on the day the event started, I kept getting this error "Your script exceeded the cpu limit." due to this some of my customers weren't getting the discount because the scripts seemed to have stopped working. Then I noticed the scripts worked on some small orders, but not big ones. Could it be that:

  1. Due to high volume of customers shopping at the same time?
  2. Script generated was too long?
    I'm going to start a new event soon but I need to know if I can rely on this. Please help !
class Campaign
  def initialize(condition, *qualifiers)
    @condition = condition == :default ? :all? : (condition.to_s + '?').to_sym
    @qualifiers = PostCartAmountQualifier ? [] : [] rescue qualifiers.compact
    @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_qualifier = nested_q if nested_q.is_a?(PostCartAmountQualifier)
          @qualifiers << qualifier
        end
      else
        @post_amount_qualifier = qualifier if qualifier.is_a?(PostCartAmountQualifier)
        @qualifiers << qualifier
      end
    end if @qualifiers.empty?
  end
  
  def qualifies?(cart)
    return true if @qualifiers.empty?
    @unmodified_line_items = cart.line_items.map(&:to_hash) if @post_amount_qualifier
    @qualifiers.send(@condition) do |qualifier|
      is_selector = false
      if qualifier.is_a?(Selector) || qualifier.instance_variable_get(:@conditions).any? { |q| q.is_a?(Selector) }
        is_selector = true
      end rescue nil
      if is_selector
        raise "Missing line item match type" if @li_match_type.nil?
        cart.line_items.send(@li_match_type) { |item| qualifier.match?(item) }
      else
        qualifier.match?(cart, @line_item_selector)
      end
    end
  end

  def revert_changes(cart)
    cart.instance_variable_set(:@line_items, @unmodified_line_items)
  end
end

class BuyXGetX < Campaign
  def initialize(condition, customer_qualifier, cart_qualifier, buy_item_selector, get_item_selector, discount, buy_x, get_x, max_sets)
    super(condition, customer_qualifier, cart_qualifier)
    @line_item_selector = buy_item_selector
    @get_item_selector = get_item_selector
    @discount = discount
    @buy_x = buy_x
    @get_x = get_x
    @max_sets = max_sets == 0 ? nil : max_sets
  end
  
  def run(cart)
    raise "Campaign requires a discount" unless @discount
    return unless qualifies?(cart)
    return unless cart.line_items.reduce(0) {|total, item| total += item.quantity } >= @buy_x
    applicable_buy_items = nil
    eligible_get_items = nil
    discountable_sets = 0
    
    # Find the items that qualify for buy_x
    if @line_item_selector.nil?
      applicable_buy_items = cart.line_items
    else
      applicable_buy_items = cart.line_items.select { |item| @line_item_selector.match?(item) }
    end
    
    # Find the items that qualify for get_x
    if @get_item_selector.nil?
      eligible_get_items = cart.line_items
    else
      eligible_get_items = cart.line_items.select {|item| @get_item_selector.match?(item) }
    end
    
    # Check if cart qualifies for discounts and limit the discount sets
    purchased_quantity = applicable_buy_items.reduce(0) { |total, item| total += item.quantity }
    discountable_sets = @max_sets ? [purchased_quantity / @buy_x, @max_sets].min : purchased_quantity / @buy_x
    return if discountable_sets < 1
    discountable_quantity = (discountable_sets * @get_x).to_i
    # Apply the discounts (sort to discount lower priced items first)
    eligible_get_items = eligible_get_items.sort_by { |item| item.variant.price }
    eligible_get_items.each do |item|
      break if discountable_quantity == 0
      if item.quantity <= discountable_quantity
        @discount.apply(item)
        discountable_quantity -= item.quantity
      else
        new_item = item.split({ take: discountable_quantity })
        @discount.apply(new_item)
        cart.line_items << new_item
        discountable_quantity = 0
      end
    end
    revert_changes(cart) unless @post_amount_qualifier.nil? || @post_amount_qualifier.match?(cart)
  end
end

class Qualifier
  def partial_match(match_type, item_info, possible_matches)
    match_type = (match_type.to_s + '?').to_sym
    if item_info.kind_of?(Array)
      possible_matches.any? do |possibility|
        item_info.any? do |search|
          search.send(match_type, possibility)
        end
      end
    else
      possible_matches.any? do |possibility|
        item_info.send(match_type, possibility)
      end
    end
  end

  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
      when :less_than
        return compare < compare_to
      when :less_than_or_equal
        return compare <= compare_to
      when :equal_to
        return compare == compare_to
      else
        raise "Invalid comparison type"
    end
  end
end

class CustomerOrderCountQualifier < Qualifier
  def initialize(comparison_type, amount)
    @comparison_type = comparison_type == :default ? :greater_than : comparison_type
    @amount = amount
  end

  def match?(cart, selector = nil)
    return false if cart.customer.nil?
    total = cart.customer.orders_count
    compare_amounts(total, @comparison_type, @amount)
  end
end

class CartQuantityQualifier < Qualifier
  def initialize(cart_or_item, comparison_type, quantity)
    @cart_or_item = cart_or_item
    @comparison_type = comparison_type
    @quantity = quantity
  end

  def match?(cart, selector = nil)
    if @cart_or_item == :item
      total = cart.line_items.reduce(0) do |total, item|
        total + selector.match?(item) ? item.quantity : 0
      end
    else
      total = cart.line_items.reduce(0) { |total, item| total + item.quantity }
    end
    compare_amounts(total, @comparison_type, @quantity)
  end
end

class Selector
  def partial_match(match_type, item_info, possible_matches)
    match_type = (match_type.to_s + '?').to_sym
    if item_info.kind_of?(Array)
      possible_matches.any? do |possibility|
        item_info.any? do |search|
          search.send(match_type, possibility)
        end
      end
    else
      possible_matches.any? do |possibility|
        item_info.send(match_type, possibility)
      end
    end
  end
end

class VariantSkuSelector < Selector
  def initialize(match_type, match_condition, skus)
    @invert = match_type == :does_not
    @match_condition = match_condition == :default ? :match : match_condition
    @skus = skus.map(&:downcase)
  end

  def match?(line_item)
    variant_skus = line_item.variant.skus.to_a.map(&:downcase)
    case @match_condition
      when :match
        return @invert ^ ((@skus & variant_skus).length > 0)
      else
        return @invert ^ partial_match(@match_condition, variant_skus, @skus)
    end
  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

CAMPAIGNS = [
  BuyXGetX.new(
    :all,
    CustomerOrderCountQualifier.new(
      :greater_than_or_equal,
      0
    ),
    CartQuantityQualifier.new(
      :cart,
      :greater_than_or_equal,
      2
    ),
    VariantSkuSelector.new(
      :does,
      :match,
      ["LN-303-2.5g", "LN-304-2.5g", "LO-202-6g", "KC-103-2.5g", "KL-403-6g", "LO-103-6g", "LO-102-6g", "LM-304-6g", "LM-204-6g", "LM-202-6g", "LM-102-6g", "LK-303-2.5g", "LF-402-2.5g", "LH-205-2.5g", "LH-203-2.5g", "LH-103-2.5g", "LH-102-2.5g", "KU-304-2.5g", "KU-203-2.5g", "KU-201-2.5g", "KU-103-2.5g", "KU-102-2.5g", "KU-101-2.5g", "KT-402-6g", "KT-303-6g", "KT-203-6g", "KS-104-6g", "KR-404-6g", "KR-301-6g", "KR-201-6g", "KQ-405-2.5g", "KQ-403-2.5g", "KJ-104-6g", "KQ-304-6g", "KQ-303-6g", "KQ-202-2.5g", "KQ-103-2.5g", "KP-304-6g", "KP-303-6g", "KP-202-2.5g", "KP-105-6g", "KO-302-6g", "KO-301-6g", "KN-202-6g", "KN-104-6g", "KN-102-6g", "KN-101-6g", "KM-402-6g", "KM-401-6g", "KM-304-6g", "KL-403-6g", "KL-402-6g", "KL-203-6g", "KL-102-6g", "KL-101-6g", "LN-101-6g", "KK-202-2.5g", "KK-201-2.5g", "KK-104-2.5g", "KK-102-2.5g", "KJ-102-6g", "KI-303-6g", "KI-103-6g", "KH-401-6g", "KH-303-6g", "KH-301-6g", "KH-203-2.5g", "KG-201-6g", "KG-104-6g", "KF-301-6g", "KE-404-6g", "KE-403-6g", "KE-202-2.5g", "KC-302-2.5g", "KC-301-2.5g", "KB-201-6g"]
    ),
    VariantSkuSelector.new(
      :does,
      :match,
      ["LN-303-2.5g", "LN-304-2.5g", "LO-202-6g", "KC-103-2.5g", "KL-403-6g", "LO-103-6g", "LO-102-6g", "LM-304-6g", "LM-204-6g", "LM-202-6g", "LM-102-6g", "LK-303-2.5g", "LF-402-2.5g", "LH-205-2.5g", "LH-203-2.5g", "LH-103-2.5g", "LH-102-2.5g", "KU-304-2.5g", "KU-203-2.5g", "KU-201-2.5g", "KU-103-2.5g", "KU-102-2.5g", "KU-101-2.5g", "KT-402-6g", "KT-303-6g", "KT-203-6g", "KS-104-6g", "KR-404-6g", "KR-301-6g", "KR-201-6g", "KQ-405-2.5g", "KQ-403-2.5g", "KJ-104-6g", "KQ-304-6g", "KQ-303-6g", "KQ-202-2.5g", "KQ-103-2.5g", "KP-304-6g", "KP-303-6g", "KP-202-2.5g", "KP-105-6g", "KO-302-6g", "KO-301-6g", "KN-202-6g", "KN-104-6g", "KN-102-6g", "KN-101-6g", "KM-402-6g", "KM-401-6g", "KM-304-6g", "KL-403-6g", "KL-402-6g", "KL-203-6g", "KL-102-6g", "KL-101-6g", "LN-101-6g", "KK-202-2.5g", "KK-201-2.5g", "KK-104-2.5g", "KK-102-2.5g", "KJ-102-6g", "KI-303-6g", "KI-103-6g", "KH-401-6g", "KH-303-6g", "KH-301-6g", "KH-203-2.5g", "KG-201-6g", "KG-104-6g", "KF-301-6g", "KE-404-6g", "KE-403-6g", "KE-202-2.5g", "KC-302-2.5g", "KC-301-2.5g", "KB-201-6g"]
    ),
    PercentageDiscount.new(
      50,
      ""
    ),
    3,
    1,
    0
  ),
].freeze

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

Output.cart = Input.cart

Feature request: 'Match all of' condition

First of all, thank you for this gem. (No pun intended)

We have a use case in which customers need to buy 2 specific qualifying products — a bundle (Product A and Product B) — in order to qualify for another bundle (Product C and Product D) at a discount. I can't seem to achieve this with the current conditions. A "Match all of" condition would be useful.

No issue, just a question

Is there a plan for this fantastic project given that Shopify as plans to deprecate/remove Shopify Scripts in favor of using Shopify Functions?

Minimum Cart Subtotal Threshold even if Free Gift is in Cart

Hello -

This is most likely due to operator error but I can't seem to figure out a solution and welcome any/all input:

We are using a "Buy X Get X Discounted" script to give someone an item for free if their cart is $99 or more. The free gift is normally $30. The problem is that if the person already has this item in their cart and say the entire value of the cart goes to $105, the discount applied to that free gift knocks the overall cart subtotal to $75. Is a BXGX Discount the wrong application here?

Thank you very much in advance -- script generator has been a life saver thus far!

Use Match Condition "end_with" + "start_with" Together

Hello - I love your software and am grateful for it!

I would like to create a Match Condition for a Cart Qualifier that checks for a match of the start or end of a given discount code.

Contains won't work for my use case, because some of my random codes contain 10, 12, 15, and 25, for example.

Is there an easy tweak I can make to the output code to quickly enable this kind of thing?

Here's an example block of code that I would like to modify to check for end_with or start_with.

CAMPAIGNS = [
ConditionalDiscountCodeRejection.new(
:all,
nil,
CodeQualifier.new(
:does_not,
:end_with,
["12", "10", "VIP", "25", "15", "AWESOME"]
),
:any,
nil,
"Not valid during New Year's Sale."
),

Thank you!

[Error] non-float value

First of all, this app is awesome. Massive thanks for making it.

I created a script to test, the contents of which is below..

{"version":"ShopifyScriptCreatorFile-V0.8.0","type":"line_item","campaigns":[{"name":"BuyXGetX","label":"Cards - 10 For £8","id":1,"inputs":[":all",{"name":"none"},{"name":"CartQuantityQualifier","inputs":[":item",":equal_to",10]},{"name":"ProductTagSelector","inputs":[":does",":match","[\"discount-title:Any 10 For £8\"]"]},{"name":"ProductTagSelector","inputs":[":does",":match","[\"discount-title:Any 10 For £8\"]"]},{"name":"PercentageDiscount","inputs":[50,"\"Any 10 Greeting Cards £8\""]},10,10,0]}]}

When running a test in Shopify script editor I get the following error..

[Error] non float value
  Shopify Script Creator:142:in CartQuantityQualifier.match?
  Shopify Script Creator:141:in CartQuantityQualifier.match?
  Shopify Script Creator:32:in Campaign.qualifies?
  Shopify Script Creator:23:in Campaign.qualifies?
  Shopify Script Creator:55:in BuyXGetX.run
  Shopify Script Creator:231:in Object.call
  Shopify Script Creator:230

Not sure if this is something I've done?

Tiered Discount - Split discount evenly between items

Thank you for creating this script creator, it is a lifesaver!

I am trying to create the following tiered discount when the code "PRESDAY" is entered at checkout:

Spend $150, get $25 off
Spend $250, get $50 off
Spend $300, get $75 off

I've selected the "Tiered Discount" campaign, added the Cart Qualifier "Cart has discount code" and entered in my code, then selected "fixed total discount" under discount type and "cart subtotal" under tier type.

The script generated worked great, but it applies the discount to each line item instead of the entire order. I noticed in the "conditional discount" campaign type there is an option to split the discount between items, and I'm wondering if there is a way to implement that logic for the tiered campaign?

Basically, if I have a cart subtotal of $150 with two items, instead of getting $25 off each item, I would get $25 off the total cart value.

I hope this makes sense! I attached photos of the setup in the script editor you created, as well as the preview of the script in the Shopify script editor. Any help is greatly appreciated!

Screenshot 2024-02-07 at 8 51 29 PM Screenshot 2024-02-07 at 8 52 02 PM

Provinces required although not always necessary

When using a Country/Province cart qualifier, a province code is required even though not all countries are set up with provinces in Shopify. Here is the current list of countries with provinces:
https://shopify.dev/docs/api/admin-rest/2023-07/resources/province#countries-that-have-provinces-in-shopify

Possible solutions:

  1. Based on the latest documentation, detect the country code and conditionally mark the field as required.
  2. If option 1 requires too much maintenance, provide a way to bypass the field with another value such as "none" or "0" and link the user to the documentation where they can see if it applies to them.

Feature request: Bundle option, "Buy X & Y for $Z"

Hello, tried doing this with the Bundle script option, but it looks like it can't.

We have item X for $40, and item Y for $30, but want to create a bundle discount where the total is $50 when they are bundled.

It looks like the current Script editor only allows for % or $ off, not setting a "new total price".

Would it be possible to add this feature?

Pull script creator file from shopify script editor?

Hey, I made two scripts using your wonderful script editor. I didn't realize until after the fact that you can't publish two scripts simultaneously. I also did not export my scripts from your editor originally.

The scripts only exist within the Shopify script editor at the moment. Is it possible for me to export them in some way from Shopify so that I can import them back into your edit and combine them into one campaign?

Payment gateway renamer

Hi there,

It seems that the Payment Gateway renaming script does not seem to work anymore. Can you reproduce this?

Reading through various threads on the internet, it seems this may be related to the fact that Shopify has updated its payment API and the way it required external payment providers to adjust their approach. Eg, since a few months, you are required to install actual "apps" as payment methods by using the app store (for example: https://apps.shopify.com/mollie-credit-card).

Do you have any insight in this?

Feature Request: And/or Shipping Name/Rate

Thanks for this creator, it's amazing.

I have a use case I'm hoping you can incorporate or advise please.

I am using a script to look for 'Standard Delivery' and rate >'3.95' to reduce the price and it is working exactly as expected.

I am now finding myself in a position where I also need to look for 'Fast track' and rate >'1.95 at the same time, I can only have 1 script running and not sure if there is a way to set this up?

Looking for Standard delivery >3.95 and/or fast track delivery >1.95

Thanks in advance.

Shopify Line Items Script Editor Errors on when :discountable_total

Good evening!

In version 0.31.0 of SSC:
I'm seeing Shopify Line Items Script Editor syntax errors for a previously working (V0.30.0) tiered discount.

This is the line I'm getting unexpected keyword syntax errors with and it seemed to be happening on the campaign initialization for tiered discounts (see attached screen recording):
" when :discountable_total"

Screen recording showing where in code/initialization the error is occurring:
Link to dropbox capture

Thanks for your help!

Mike

Valid script creator file

Which are compatible file formats to import campaigns? So far .rb and .txt formats are "File does not appear to be a valid script creator file." Thank you!

Cart Qualifier - "Multi-Select - Meets all conditions" with "Discounted Cart Subtotal (applied by scripts)" not working

I noticed what looks like a bug - as follows:

Steps to reproduce

  1. Create a new campaign type "Conditional Discount" which uses a Cart Qualifier of "Multi-Select - Meets all conditions".
  2. Add two conditions, each one being "Discounted Cart Subtotal (applied by scripts)". These conditions should restrict the discount to only apply between X and Y cart subtotal values (e.g. £60-89.99)
  3. Add discounted item selector, and specify a SKU - apply discount a maximum of 1 time and set to 100%

Config file to reproduce example:

{"version":"ShopifyScriptCreatorFile-V0.34.2","type":"line_item","campaigns":[{"name":"ConditionalDiscount","active":true,"label":"GWP Tier 1","id":11,"inputs":[":all",{"name":"none"},{"name":"AndSelector","inputs":[{"name":"PostCartAmountQualifier","inputs":[":greater_than_or_equal",60]},{"name":"PostCartAmountQualifier","inputs":[":less_than_or_equal",89.99]},{"name":"none"}]},{"name":"VariantSkuSelector","inputs":[":does",":match","[\"SBFCW200\"]"]},{"name":"PercentageDiscount","inputs":[100,"\"Free Gift when you spend £60-80.99\""]},1]}]}

image

Expected result

The discount should only be applied if the cart subtotal is within £60-89.99 after discounts are / would have been applied.

Observed behaviour

The discount is applied to the cart subtotal, rather than the cart subtotal after discounts have been applied by scripts.

E.g. The customer is only actually spending £49, but they still get the discounted item. They need to be spending £60-89.99.

image

Notes

This behaviour works fine when using "Discounted Cart Subtotal (applied by scripts)" cart qualifier, but not when using "Multi-Select - Meets all conditions" with "Discounted Cart Subtotal (applied by scripts)".

ExcludeDiscountCodes - :reject_except not running when behaviour is :apply_discount

If you use ExcludeDiscountCodes with behaviour :apply_discount and add a discount code in the exceptions,

    ExcludeDiscountCodes.new(
      :apply_discount,
      "",
      :reject_except,
      ["DISCOUNT15"]
    ),

The exception will not run because this automatically returns false before the matching script

@reject = behaviour == :apply_script
...
return false if !@reject

Og Code

class ExcludeDiscountCodes < Qualifier
  def initialize(behaviour, message, match_type = :reject_except, discount_codes = [])
    @reject = behaviour == :apply_script
    @message = message == "" ? "Discount codes cannot be used with this offer" : message
    @match_type = match_type
    @discount_codes = discount_codes.map(&:downcase)
  end

  def match?(cart, selector = nil)
    return true if cart.discount_code.nil?
    return false if !@reject
    discount_code = cart.discount_code.code.downcase
    should_reject = true
    case @match_type
      when :reject_except
        should_reject = !@discount_codes.include?(discount_code)
      when :accept_except
        should_reject = @discount_codes.include?(discount_code)
    end
    if should_reject
      cart.discount_code.reject({message: @message})
    end
    return true
  end
end

My suggestions is to add a condition in returning false only if there are no discount code exceptions

return false if !@reject and @discount_codes.empty?

Runtime error

Hi,

There is a "runtime error" with this code:

class GiftCardSelector < Selector
def initialize(match_type)
@invert = match_type == :not
end def match?(line_item)
@invert ^ line_item.variant.product.gift_card?
end
end

Bundle pricing issue bug

Hello,

We're setting up a bundle pricing of $199.99 for 2 items. The original price of an item is $109.99. each discount item should be $9.995 if user purchase in a bundle. However on checkout, the script keeps reading it as $20 discounted instead. it should be $19.99 ...

Screenshot 2022-08-04 at 9 57 21 PM

Feature request: use Bundle discount with most discount

Thank you for this amazing tool you created.

So, I have line-item script where there are multiple Bundle Discounts, with same or different products and percentages as discounts.

Now, when there are products that qualifies for multiple Bundle Discounts, the first BundleDiscount is applied.
Is there a way to actually use BundleDiscount that gives the most amount of discounts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.