How to Modify Discount Code Logic Shopify - graphql

I have a discount code which gives 40% discount when there are more than 50 items, but this also works if I have for example 49 items + 1 other item. I want to make the code work only for the single items that have a quantity over 50.
I assume this would be pretty straight forward if I could access this logic myself. Can someone point me into whereabouts could I find these codes for my discounts?
I would also want my discount code to give 40% for items over 50 quantity, and 50% for items over 200 quantity.
I have found something called "Shopify GraphiQL App" which, if I understand correctly, would help me to modify these discount codes internally.
Any help is appreciated.
Thanks
EDIT
I have been playing a bit with GraphiQL, and I have found the priceRule has a field called: allocationMethod (PriceRuleAllocationMethod).
The value of this is ACROSS. Would my discount code have the desired behaviour if I manage to change this to EACH?
How can I modify this, I haven't been able to find an example.
EDIT 2
I have tried the following, but for some reason the allocation method is not updated. Can someone explain to me what is happening here?

I think you can do this using Liquid in the theme.liquid file:
{% assign num = 0 %}
{% for item in cart.items %} #finding how many items in cart
{% capture temp %}{{ num | plus: item.quantity }}{% endcapture %}
{% endif %}
{% assign num = temp %}
{% endfor %}
{% assign new_num = num | plus: 0 %} #converting string to integer
{% if new_num >= 50 %}
{% assign price = checkout.subtotal_price %}
{{ price | times: 0.40 }} #40 percent
{{ checkout.subtotal_price | minus: price }}
{% endif %}
Edit: Maths was wrong in first edit, that should be correct now.

Related

Shopify Theme Development | Creating a 're-order' link for previous orders | Unable to chain multiple ID:quantity query strings

I am using Shopify and creating a re-order button within the file named order.liquid.
while trying to create the re-order button I have had a moderate level of success.
The script I attach does indeed add the items to the cart that were previously ordered. However, I have tried without adding the quantity (just adds 1 of each). Without the [] after the &quantityHERE= (just adds two of each even if it was previously only one item bought).
Heres the code that creates my half-working URL:
{% assign line_items_string = '/cart/' %}
{% for line_item in order.line_items %}
{% if forloop.first == true %}
{% assign line_items_string = line_items_string | append: 'add?id[]=' %}
{% assign line_items_string = line_items_string | append: line_item.variant_id %}
{% assign line_items_string = line_items_string | append: '&quantity[]=' %}
{% assign line_items_string = line_items_string | append: line_item.quantity %}
{% else %}
{% assign line_items_string = line_items_string | append: '&id[]=' %}
{% assign line_items_string = line_items_string | append: line_item.variant_id %}
{% assign line_items_string = line_items_string | append: '&quantity[]=' %}
{% assign line_items_string = line_items_string | append: line_item.quantity %}
{% endif %}
{% endfor %}
Re-order
I am unable to get it to add the correct amount of items per line item even though the URL appears correct:
/cart/add?id[]=16220586868785&quantity[]=3&id[]=16220587360305&quantity[]=6&id[]=16220587622449&quantity[]=4&id[]=16221376479281&quantity[]=11&id[]=16221376348209&quantity[]=2&id[]=16221063938097&quantity[]=1&id[]=16221393682481&quantity[]=2
The fact the string ends with quantity 2 and will then add 2 of each item suggests it only uses the last declaration of quantity when dealing with the link. Therefore there must be a separator that can be used to distinguish between line items.
What is the separator that would go between each line items addition to the query string please? What goes after?
add?id[]=16220586868785&quantity[]=3**HERE**
I have tried using a , but admittedly this looks out of place followed by an &.
Edit
To help describe further what I have tried.
I am able to use the format ID:quantity if I:
want to go straight to checkout, the format is ID:quantity,ID:quantity.. so on.
only wish to add one item of a certain quantity to cart using add?ID:Quantity.
I need to know how to chain multiple to only add to cart. I don't know the separator (that is a comma when pushing straight to checkout).
Using permalinks to re-order things is always the ID:quantity. Have you tried that?
I would consider implementing this using jquery or javascript. You can create an ajax post using the cart/add.js call described here: https://help.shopify.com/en/themes/development/getting-started/using-ajax-api#add-to-cart

Business Catalyst Liquid sorting

I can see that Liquid allows you to sort a collection using the below syntax:
{% assign sorted_items = items.all|sort:'Email' %}
{% for item in sorted_items %}
<div>Name: {{item.name}}</div>
<div>Email: {{item.email}}</div>
{% endfor %}
However this does not appear to work in Business Catalyst.
If I use this to render the result to the page it simply renders "null".
{{sorted_items | json }}
Should I be able to do this in Business Catalyst, or am I completely wasting my time trying to find a solution to sort my WebApp data?
You can sort the data like this:
{module_data resource="customers" version="v3" fields="firstName,email1" collection="myData"}
<pre>{{myData|json}}</pre>
{% capture emails -%}
{% for item in myData.items -%}
,{{ item.email1.value }} - {{ item.firstName }};
{% endfor %}
{% endcapture %}
<pre>{{ emails | split: "," | sort }}</pre>
The comma is not spelling mistake : )
After you split the string in array you can do whatever you need to do with it.
The answer from Daut is not good. Any solution in the for loop will only sort the number of items fetched from the module and the max amount for that is 500.
If you are using module_data you just use its actual sort!
{module_data resource="customers" version="v3" order="firstName" fields="firstName,email1" collection="myData"}
module_data supports both WHERE for filtering and ORDER to order the results.

Create a filter list of items where a filter item appears only if there is a story for the product

I'm trying to figure out how to create a filter list where it grabs the product title from a _products directory and it will show the title in the list only if there is a story with the title of the product.
I have a _products list with 11 items and I can show them all, but I want to remove an item from the list of filter items if it's title != a element in the front matter of a list of stories in a separate directory.
{% assign product = site.products %}
{% for product in site.products %}
{% for success in site.success-stories %}
{% if product.title == success.product %}
<li><p class="filter label label-default" data-filter=".{{product.title | downcase}}">{{product.title}}</p></li>
{% endif %}
{% endfor %}
{% endfor %}
What this does is shows only the items that have a matching success-story but if there are multiple stories with the same product in it's front matter it will show that product more than once.
I've got the filtering down, it's just showing the items I can't get down.
Thanks!
I have a feeling you are looking for the contains filter.
Taken directly from the Liquid for Designers wiki:
# array = 1,2,3
{% if array contains 2 %}
array includes 2
{% endif %}
In your case, I'm guessing you want:
{% assign product = site.products %}
{% assign successfulProducts = site.success-stories | map: 'product' %}
{% for product in site.products %}
{% if successfulProducts contains product.title %}
... {{ product }} ...
{% endif %}
{% endfor %}
All I've done here in line 2 is mapping success-stories to successfulProducts. Essentially each story element is replaced by its story.product property.
Then I loop through all the products like you and check each one if it should be displayed. But I don't loop through all the stories - instead I put a simple condition that checks if successfulProducts contains the product title, just as you specified.

Capturing Item Index in Collection

I was wondering what is the proper way of finding the index of an item in an array is in a Liquid template, and selected related items based off of the index. Currently I'm able to calculate the value, but it seems to be a string and I can't then find other items in the array with the string. For example in a CMS:
{% for site_page in site.pages.all %}
{% if site_page.id == page.id %}
{% assign page_index = forloop.index0 %}
{% capture previous_page_index %}
{{ page_index | minus: 1 }}
{% endcapture %}
{% break %}
{% endif %}
{% endfor %}
The expected value can be found in previous_page_index (in this case 0) however, if i try to do something like site.pages.all[previous_page_index] I receive no output. If I do the same thing with a hardcoded index value: site.pages.all[0] it does yield an output. Does anyone have an idea/example on how this is supposed to be done in liquid?
Best I can figure is to use {% for item in array limit:1 offset:forloop.index0 %}. For example:
require 'liquid'
chars = %w[a b c]
names = %w[alpha bravo charlie]
puts Liquid::Template.parse(<<DONE).render( 'chars'=>chars, 'names'=>names )
{% for c in chars %}
{{c}} is
{% for n in names limit:1 offset:forloop.index0 %}{{n}}{% endfor %}
{% endfor %}
DONE
…which produces…
a is
alpha
b is
bravo
c is
charlie
Editorial aside: ouch. What an ugly tempting language. I understand its goals, but the burden it places on users is heinous.

Related Products Shopify Liquid

I'm trying to determine the correct Shopify Liquid syntax for outputting a list of products that match the same tag as the current product.
This is to appear in a "Related Products" box on the product page, and I'd like it only to list other products that match the same tag of the current product page.
Unfortunately the Related Products wiki page didn't help me with this.
I'm not sure you can get a set of all products with a common tag (although I may be wrong) but here's a possible alternative way to approach it - create a smart collection of products that contain that tag, then output the products from that collection in the related items area.
To connect the product tag to the right collection on the product page, make sure that your collection handle is the same as the tag you're using, then do something like this to grab the right collection based on the tag.
{% for c in collections %}
{% assign t = {{product.tags[0] | handleize}} %}
{% if c.handle == t %}
{% assign collection = c %}
{% endif %}
{% endfor %}
Then just output the products in the collection using the approach outlined in the wiki article you linked.
Something like this (assuming you use a "product-loop" include approach) should do the trick:
{% assign current_product = product %}
{% assign current_product_found = false %}
{% for product in collection.products %}
{% if product.handle == current_product.handle %}
{% assign current_product_found = true %}
{% else %}
{% unless current_product_found == false and forloop.last %}
{% include 'product-loop' with collection.handle %}
{% endunless %}
{% endif %}
{% endfor %}

Resources