New Shopify Certification now available: Liquid Storefronts for Theme Developers

Checkout and Cart Validation Extension should only fire on /checkout not on adding products to cart

Solved
Erik_Abrio
Shopify Partner
21 5 2

Hello, In our new shop we have following shipping requirements: Non frozen products can be shipped at any Time, frozen products have to have a weight of at least 4000 grams.

 

To Validate this Requirements i wrote following checkout and cart validation extension.

Its working pretty much correcty, but it fires the error while im adding products to an empty cart and when i want to reduce the quantity of frozen products to a weight of under 4000 grams. How can i make this extension only throwing errors when on checkout site and keep shop functionality working in my shop?.

 

Best Regards

 

/**
 * @typedef {import("../generated/api").InputQuery} InputQuery
 * @typedef {import("../generated/api").FunctionResult} FunctionResult
 */

export default /**
 * @param {InputQuery} input
 * @returns {FunctionResult}
 */
(input) => {
  const min_weight_frozen = 4000;
  let sum_weight_frozen = 0
  let item_count_frozen = 0

  for(let item of input.cart.lines){
    if(item.quantity){
      if(item.merchandise?.product?.lagerung.value.includes("TK") || item.merchandise?.product?.eigenschaften.value.includes("gefroren") || item.merchandise?.product?.hinweis.value.includes("Gefroren")){
        if(item.merchandise?.weightUnit == "KILOGRAMS"){
          sum_weight_frozen += item.merchandise.weight * 1000 * item.quantity
        }
        else{
          sum_weight_frozen += item.merchandise.weight * item.quantity
        }
        item_count_frozen += 1
      }
    }
  }

  let cart_is_valid = false
  if(sum_weight_frozen >= min_weight_frozen && item_count_frozen != 0){
    cart_is_valid = true
  }
  else if(item_count_frozen == 0){
    cart_is_valid = true
  }

  const min_weight_frozen_kg = min_weight_frozen / 1000
  const sum_weight_frozen_kg = sum_weight_frozen / 1000

  let input_string = JSON.stringify(input)
  const weightError = {
    localizedMessage: `Wir versenden gefrorene Produkte erst ab einem gesamt Mindestgewicht von ${min_weight_frozen_kg}kg. Das gesamt Gewicht Ihrer gefrorenen Produkte liegt bei ${sum_weight_frozen_kg}kg. ${sum_weight_frozen} ${item_count_frozen} ${input_string} hallo`,
      target: "cart"
  }
    let errors = []
  if(cart_is_valid == false){
    errors.push(weightError)
  }

  return {
    errors
  }
};
Accepted Solution (1)
Erik_Abrio
Shopify Partner
21 5 2

This is an accepted solution.

Hi CSilvas,

 

I have a Solution for my Problem if i check the buyerJourney step before

 

Thats my updated query.

query Input {
  buyerJourney{
    step
  }
  cart {
    lines {
      quantity
      merchandise{
        ...on ProductVariant {
          id
          weight
          weightUnit
          product {
            lagerung:metafield(namespace:"sl_ART",key:"extra_LAGERUNGSEMPFEHLUNG"){
              
              value
            }
            eigenschaften:metafield(namespace:"sl_ART",key:"extra_PRODUKTEIGENSCHAFTEN"){
              
              value
            }
            hinweis:metafield(namespace:"sl_ART",key:"extra_HINWEISWICHTIG"){
              
              value
            }
          }
        }
      }
    }
  }
}

.

Thats my new Code:

// @TS-check

/**
 * @typedef {import("../generated/api").InputQuery} InputQuery
 * @typedef {import("../generated/api").FunctionResult} FunctionResult
 */

export default /**
 * @param {InputQuery} input
 * @returns {FunctionResult}
 */
(input) => {
  let errors = []
  if(input.buyerJourney.step != "CART_INTERACTION"){
  const min_weight_frozen = 4000;
  let sum_weight_frozen = 0
  let item_count_frozen = 0
  for(let item of input.cart.lines){
    if(item.quantity){
      if(item.merchandise?.product?.lagerung?.value?.includes("TK") || item.merchandise?.product?.eigenschaften?.value?.includes("gefroren") || item.merchandise?.product?.hinweis?.value?.includes("Gefroren")){
        if(item.merchandise?.weightUnit == "KILOGRAMS"){
          sum_weight_frozen += item.merchandise.weight * 1000 * item.quantity
        }
        else{
          sum_weight_frozen += item.merchandise.weight * item.quantity
        }
        item_count_frozen += 1
      }
    }
  }

  let cart_is_valid = false
  if(sum_weight_frozen >= min_weight_frozen && item_count_frozen != 0){
    cart_is_valid = true
  }
  else if(item_count_frozen == 0){
    cart_is_valid = true
  }
  const min_weight_frozen_kg = min_weight_frozen / 1000
  const sum_weight_frozen_kg = sum_weight_frozen / 1000

  const weightError = {
    localizedMessage: `Wir versenden gefrorene Produkte erst ab einem gesamt Mindestgewicht von ${min_weight_frozen_kg}kg. Das Gesamtgewicht Ihrer gefrorenen Produkte liegt bei ${sum_weight_frozen_kg}kg.`,
      target: "$.cart"
  }
  
  if(cart_is_valid == false){
    errors.push(weightError)
  }
  }


  return {
    errors
  }
};

 Im pushing my custom Error only when not in buyerJourney.step = "CART_INTERACTION"

Possible Values for this you can find here

View solution in original post

Replies 2 (2)
CSilvas
Shopify Partner
1 0 0

Oddly enough, I have the exact opposite problem. I have a validation script I would like to run at Cart and Checkout level but it is only running at Checkout. Would you like to compare notes and see if we can switch our situations :D!?

 

import type { RunInput, FunctionRunResult } from "../generated/api";

export function run(input: RunInput): FunctionRunResult {
  if (
    input.cart.lines.length > 0 &&
    !(
      // For some reason Shopify reverses the order of cart lines when a customer clicks the "Check out" button.
      // We compensate by allowing the signature to be at the beginning or the end of the lines.
      (
        input.cart.lines[0].signature?.value?.length == 64 ||
        input.cart.lines[input.cart.lines.length - 1].signature?.value
          ?.length == 64
      )
    )
  ) {
    return {
      errors: [
        {
          localizedMessage:
            "Something unexpected happened. Please contact support!",
          target: "cart",
        },
      ],
    };
  }

  return {
    errors: [],
  };
}
Erik_Abrio
Shopify Partner
21 5 2

This is an accepted solution.

Hi CSilvas,

 

I have a Solution for my Problem if i check the buyerJourney step before

 

Thats my updated query.

query Input {
  buyerJourney{
    step
  }
  cart {
    lines {
      quantity
      merchandise{
        ...on ProductVariant {
          id
          weight
          weightUnit
          product {
            lagerung:metafield(namespace:"sl_ART",key:"extra_LAGERUNGSEMPFEHLUNG"){
              
              value
            }
            eigenschaften:metafield(namespace:"sl_ART",key:"extra_PRODUKTEIGENSCHAFTEN"){
              
              value
            }
            hinweis:metafield(namespace:"sl_ART",key:"extra_HINWEISWICHTIG"){
              
              value
            }
          }
        }
      }
    }
  }
}

.

Thats my new Code:

// @TS-check

/**
 * @typedef {import("../generated/api").InputQuery} InputQuery
 * @typedef {import("../generated/api").FunctionResult} FunctionResult
 */

export default /**
 * @param {InputQuery} input
 * @returns {FunctionResult}
 */
(input) => {
  let errors = []
  if(input.buyerJourney.step != "CART_INTERACTION"){
  const min_weight_frozen = 4000;
  let sum_weight_frozen = 0
  let item_count_frozen = 0
  for(let item of input.cart.lines){
    if(item.quantity){
      if(item.merchandise?.product?.lagerung?.value?.includes("TK") || item.merchandise?.product?.eigenschaften?.value?.includes("gefroren") || item.merchandise?.product?.hinweis?.value?.includes("Gefroren")){
        if(item.merchandise?.weightUnit == "KILOGRAMS"){
          sum_weight_frozen += item.merchandise.weight * 1000 * item.quantity
        }
        else{
          sum_weight_frozen += item.merchandise.weight * item.quantity
        }
        item_count_frozen += 1
      }
    }
  }

  let cart_is_valid = false
  if(sum_weight_frozen >= min_weight_frozen && item_count_frozen != 0){
    cart_is_valid = true
  }
  else if(item_count_frozen == 0){
    cart_is_valid = true
  }
  const min_weight_frozen_kg = min_weight_frozen / 1000
  const sum_weight_frozen_kg = sum_weight_frozen / 1000

  const weightError = {
    localizedMessage: `Wir versenden gefrorene Produkte erst ab einem gesamt Mindestgewicht von ${min_weight_frozen_kg}kg. Das Gesamtgewicht Ihrer gefrorenen Produkte liegt bei ${sum_weight_frozen_kg}kg.`,
      target: "$.cart"
  }
  
  if(cart_is_valid == false){
    errors.push(weightError)
  }
  }


  return {
    errors
  }
};

 Im pushing my custom Error only when not in buyerJourney.step = "CART_INTERACTION"

Possible Values for this you can find here