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
{%- capture variant_json -%}
{%- for variant in product.variants -%}{{ variant.id }}~{{ variant.title }}~{{ variant.available }}~{{ variant.inventory_quantity }}{% unless forloop.last %},{% endunless %}{%- endfor -%}
{%- endcapture -%}
{% if current_variant.available and current_variant.inventory_quantity <= 0 %}
{% echo 'products.product.pre_order_description' | t %}
{% endif %}
{%- if settings.enable_payment_button -%}
{{ form | payment_button }}
{%- endif -%}
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;
}
}
}
}