Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

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

Solved

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

Erik_Abrio
Shopify Partner
29 6 10

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
29 6 10

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 /**
 * @Anonymous {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
3 0 1

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
29 6 10

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 /**
 * @Anonymous {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