Pre-order line item property not always send

Pre-order line item property not always send

Paul_vd_Dool
Shopify Partner
114 6 100

For a client, I've added line item properties when a product is available for pre-order.

 

 

{%  if current_variant.available and current_variant.inventory_quantity <= 0 %}

 

 

If the variant is available and the inventory_quantity is 0 or less, then the line item property is added.

 

This change went live some time ago, but it turns out that it does not seem to work all the time. Every day, some orders come in where the pre-order line item property is not set.

I can't find a correlation between the orders that went wrong and the orders that went correct.

The exact same product can be ordered on the exact same day and for one the line item property is added, but for the other it isn't.
It's also doesn't seem to be due the product having multiple variants and the line item property being wrongly set when changing the variant. The client mostly has products with a single variant and in those cases the line item property is already set on the server side.

It doesn't seem to be due to the payment method or checkout method as I've had issues before where "Buy now" buttons would bypass the checkout and line item properties weren't properly set.
It's been quite a few weeks since the change went live so it can't be related to caching or it can't be that people had the product in their cart already before the change went live and they came back later to order it.
Whatever we do, we can't seem to reproduce the issue.

Does anybody have an idea what could be wrong?
I'll share some of my code snippets below.


On the product page

 

<div class="product-single__add-to-cart">
                    {%- capture variant_json -%}
                      {%-  for variant in product.variants -%}{{ variant.id }}~{{ variant.title }}~{{ variant.available }}~{{ variant.inventory_quantity }}{% unless forloop.last %},{% endunless %}{%- endfor -%}
                    {%- endcapture -%}
                    <span id="pre-order-data"
                      data-message="{{ 'products.product.pre_order_description' | t }}"
                      data-pre-order-label="{{ 'products.product.pre_order' | t }}"
                      data-available-label="{{ 'products.product.add_to_cart' | t }}"
                      data-sold-out-label="{{ 'products.product.sold_out' | t }}"
                      data-variants="{{ variant_json }}"
                      data-form-id="AddToCartForm--{{ section.id }}"
                      ></span>
                    <div id="pre-order-description">
                      {%  if current_variant.available and current_variant.inventory_quantity <= 0 %}
                        <input type="hidden" name="properties[Order]" value="Pre-order" form="{{ 'AddToCartForm--' | append: section.id }}" />
                        <p style="color: red">{% echo 'products.product.pre_order_description' | t %}</p>
                      {% endif %}
                    </div>
                    <button type="submit" name="add" id="AddToCart--{{ section.id }}" class="btn btn--primary  add-to-cart btn--add-to-cart full"{% unless current_variant.available %} disabled="disabled"{% endunless %}>
                      <span class="btn__text">
                        <span class="{{ settings.icon }} button-cart-icon">{{ settings.icon_cart }}</span>
                        <span class="btn__add-to-cart-text--original">
                          {%- if current_variant.available -%}
                            {%- if current_variant.inventory_quantity > 0 -%}
                              {{ 'products.product.add_to_cart' | t }}
                            {%- else -%}
                              {{ 'products.product.pre_order' | t }}
                            {%- endif -%}
                          {%- else -%}
                            {{ 'products.product.sold_out' | t }}
                          {%- endif -%}
                        </span>
                      </span>
                    </button>

                    {%- if settings.enable_payment_button -%}
                      {{ form | payment_button }}
                    {%- endif -%}
                  </div>

 


Catching the variant change and updating text and adding line item property when necessary.

 

function checkVariantAvailability( selection ) {
    const preOrderBlock = document.querySelector( '#pre-order-description' );
    if ( preOrderBlock ) {
      // get data from template
      const addToCartButtonText = document.querySelector( '.btn__add-to-cart-text--original' );
      const preOrderData = document.querySelector( '#pre-order-data' );
      const preOrderDescription = preOrderData?.getAttribute('data-message');
      const preOrderLabel = preOrderData?.getAttribute('data-pre-order-label');
      const availableLabel = preOrderData?.getAttribute('data-available-label');
      const soldOutLabel = preOrderData?.getAttribute('data-sold-out-label');
      const preOrderFormId = preOrderData?.getAttribute('data-form-id');
      const variantString = preOrderData?.getAttribute('data-variants');
      const variantsRaw = variantString?.split(',');
      const variants = variantsRaw?.map( v => {
        const [ id, name, available, quantity ] = v?.split('~');
        return { id, name, available: available === 'true' ? true : false, quantity: Number(quantity) };
      } );
  
      // determine currentVariant
      let currentVariant;
      if ( variants?.length > 0 && !!selection ) {
        currentVariant = variants.find( v => v.name === selection );
      }

      if ( !!currentVariant ) {
        if ( currentVariant.available && currentVariant.quantity <= 0 ) {
          // Variant available for pre-order
          // Update button label
          addToCartButtonText.innerHTML = preOrderLabel;
          
          // update description
          // create hidden input element for line item properties
          const inputElement = document.createElement("input");
          inputElement.type = "hidden";
          inputElement.name = "properties[Order]";
          inputElement.value = "Pre-order";
          inputElement.setAttribute("form", preOrderFormId);
      
          // Create the paragraph element with pre-order message
          const paragraphElement = document.createElement("p");
          paragraphElement.style.color = "red";
          paragraphElement.textContent = preOrderDescription
    
          // Empty div in case it contains something
          preOrderBlock.innerHTML = '';
      
          // Append the elements to the div
          preOrderBlock?.appendChild(inputElement);
          preOrderBlock?.appendChild(paragraphElement);
        } else if ( !currentVariant.available ) {
          // Variant sold out
          // Clear pre-order block
          preOrderBlock.innerHTML = '';
          // Update button label
          addToCartButtonText.innerHTML = soldOutLabel;
        } else {
          // Variant available
          // Clear pre-order block
          preOrderBlock.innerHTML = '';
          // Update button label
          addToCartButtonText.innerHTML = availableLabel;
        }
      }
    }
  }

 


 

Doppelganger - Managing duplicate user accounts
Replies 3 (3)

JayAdra
Shopify Partner
181 15 47

Does the store in question have Quick Add buttons on the Collection pages or something similar, where they can ATC from another page?

Paul_vd_Dool
Shopify Partner
114 6 100

No. That was also one of my first instincts, but they have nothing of the sort.

Doppelganger - Managing duplicate user accounts

Sandy--STOQ
Shopify Partner
90 5 11

@Paul_vd_Dool 👋🏼 Were you able to figure this out?

We ran into a merchant that had a similar issue recently and they decided to install our Preorder app - STOQ - to get ahead of the troubles. Since they already had somewhat of a working solution, my recommendation to them was to add a Javascript snippet to read any 'Add to cart' API calls on the product page and add in the line item property if it's not there. This is what most preorder apps do btw, since the form submission can be unreliable.

STOQ: Unlock more sales with Back in stock alerts & Preorders
Filemonk: Sell digital products & downloads in 3 quick steps

Founder & CEO, Artos Software