I’m currently developing a web store on Shopify with some specific needs that has led to some code in order to facilitate these needs. Some background;
- The store will sell both preorder and premade items
- Premade and Preorder items may not occupy a cart together due to the turnaround time of preorder items (~20 weeks from order to shipment)
- Premade items are paid in full upon ordering and sent within a business day or two
- Preorder items are paid for with a 50% deposit on order creation and the other 50% paid via invoice upon completion of the item
I have been able to fulfil all the needs here in pretty basic ways, I’ve been able to sort preorder and premade items into separate collections, which means the 50% deposit is applied as a discount to items in the preorder collection. The only issue I have run into is the pretty rudimentary (and hardly watertight) solution for stopping preorder and premade items occupying a cart. I’ve used some basic liquid to check if items in the customer’s cart conflict with the current item they are viewing, if they can’t share a cart, the button is not created on the page, rather just some text saying they can’t add the item. The solution works fine for the store, due to the nature of what it’s selling it’s very unlikely customers will go out of their way to check out with an invalid cart. For its intended function the code works perfectly and doesn’t act up.
The only issue is that somehow, despite all the code for hiding the button being contained within the product-template.liquid, the cart page encounters a really weird bug where a customer adds a pre-order item (in a valid manner). The item will show in the cart with the deposit discount applied, and the subtotal will be correct, however, the item will show as $0. This bug only applies for pre-order items with the automatic discount.
This bug only persists for a bit, after two or so refreshes it tends to correct itself.
Visual of the cart acting normally after the bug is gone
I don’t understand how this code is interfacing with the cart in an odd manner despite being separate from the product page code and only ever getting the state of the cart, never setting. I’ve tried isolating the code that hides the add to cart button, and the bug is not present. I’m pretty new to Shopify so I’m wondering if I’ve made an odd oversight or am missing something obvious.
The block of code in ‘product-template.liquid’ that includes the logic and introduces the bug:
{% assign in_preorder_collection = false %}
{% for collection in product.collections %}
{% if in_preorder_collection == false and collection.title == 'Pre-Order' %}
<div>
<p style="color:green;font-size:0.75em">
Pay a 50% deposit per item
</p>
</div>
{% assign in_preorder_collection = true %}
{% endif %}
{% endfor %}
<div class="product-form__controls-group product-form__controls-group--submit">
<div class="product-form__item product-form__item--submit
{%- if section.settings.enable_payment_button %} product-form__item--payment-button {%- endif -%}
{%- if product.has_only_default_variant %} product-form__item--no-variants {%- endif -%}"
>
{% assign allow_flag = true %}
{% if in_preorder_collection %}
{% for item in cart.items %}
{% for collection in item.product.collections %}
{% if collection.title == 'Pre-Built' %}
{% for collection in product.collections %}
{% if collection.title == 'Pre-Order' %}
<h2>Pre-Built and Pre-Order Items cannot be in the same Cart</h2>
{% assign allow_flag = false %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% else %}
{% for item in cart.items %}
{% for collection in item.product.collections %}
{% if collection.title == 'Pre-Order' %}
{% for collection in product.collections %}
{% if collection.title == 'Pre-Built' %}
<h2>Pre-Built and Pre-Order Items cannot be in the same Cart</h2>
{% assign allow_flag = false %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
{% endif %}
{% if allow_flag %}
<button type="submit" name="add"
{% unless current_variant.available %} aria-disabled="true"{% endunless %}
aria-label="{% unless current_variant.available %}{{ 'products.product.sold_out' | t }}{% else %}{{ 'products.product.add_to_cart' | t }}{% endunless %}"
class="btn product-form__cart-submit{% if section.settings.enable_payment_button and product.selling_plan_groups == empty %} btn--secondary-accent{% endif %}"
{% if settings.enable_ajax %}aria-haspopup="dialog"{% endif %}
data-add-to-cart>
<span data-add-to-cart-text>
{% unless current_variant.available %}
{{ 'products.product.sold_out' | t }}
{% else %}
{{ 'products.product.add_to_cart' | t }}
{% endunless %}
</span>
<span class="hide" data-loader>
{% include 'icon-spinner' %}
</span>
</button>
{% if section.settings.enable_payment_button %}
{{ form | payment_button }}
{% endif %}
</div>
</div>
{% endif %}
{% endform %}
</div>
And here is the same code without the logic, removing the bug;
<div>
<p style="color:green;font-size:0.75em">
Pay a 50% deposit per item
</p>
</div>
<div class="product-form__controls-group product-form__controls-group--submit">
<div class="product-form__item product-form__item--submit
{%- if section.settings.enable_payment_button %} product-form__item--payment-button {%- endif -%}
{%- if product.has_only_default_variant %} product-form__item--no-variants {%- endif -%}">
<button type="submit" name="add"
{% unless current_variant.available %} aria-disabled="true"{% endunless %}
aria-label="{% unless current_variant.available %}{{ 'products.product.sold_out' | t }}{% else %}{{ 'products.product.add_to_cart' | t }}{% endunless %}"
class="btn product-form__cart-submit{% if section.settings.enable_payment_button and product.selling_plan_groups == empty %} btn--secondary-accent{% endif %}"
{% if settings.enable_ajax %}aria-haspopup="dialog"{% endif %}
data-add-to-cart>
<span data-add-to-cart-text>
{% unless current_variant.available %}
{{ 'products.product.sold_out' | t }}
{% else %}
{{ 'products.product.add_to_cart' | t }}
{% endunless %}
</span>
<span class="hide" data-loader>
{% include 'icon-spinner' %}
</span>
</button>
{% if section.settings.enable_payment_button %}
{{ form | payment_button }}
{% endif %}
</div>
</div>
{% endform %}
</div>
Any help is extremely appreciated! Thanks for your time ![]()