Re: Potential bug with product discount extension when targeting productVariant

Solved

Potential bug with product discount extension when targeting productVariant

benjamin_h
Shopify Partner
2 0 2

We're building a custom product discount extension with Shopify Functions. We've got some of the functionality working, but have noticed an unexpected outcome when the same product variant exists across multiple lines. We're developing with the .js variant of the extension and are currently using api_version 2024-07 but have tested with 2024-04 as well.

 

run.graphql:

query RunInput {
  cart {
    lines {
      id
      cost {
        amountPerQuantity {
          amount
        }
      }
      quantity
      att1: attribute(key: "Stamp Style") {
        value
      }
      att2: attribute(key: "Symbol") {
        value
      }
      merchandise {
        __typename
        ... on ProductVariant {
          id
          product {
            id
            metafield(key: "retail", namespace: "pricing",) {
              type
              value
            }
          }
        }
      }
    }
  }
  discountNode {
    metafield(
      namespace: "$app:standard-pricing"
      key: "function-configuration"
    ) {
      value
    }
  }
}

 run.js:

 

 

// -check
import { DiscountApplicationStrategy } from "../generated/api";

/**
 * @typedef {import("../generated/api").RunInput} RunInput
 * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
 * @typedef {import("../generated/api").Target} Target
 * @typedef {import("../generated/api").ProductVariant} ProductVariant
 */

/**
 *  {FunctionRunResult}
 */
const EMPTY_DISCOUNT = {
  discountApplicationStrategy: DiscountApplicationStrategy.All,
  discounts: [],
};

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  const discounts = input.cart.lines
    .map(line => {
      const variant = /**  {ProductVariant} */ (line.merchandise);

      const currentprice = parseFloat(line.cost.amountPerQuantity.amount);
      const baseprice100 = parseFloat(variant.product.metafield?.value);
      const baseprice = baseprice100 / 100;
      const discountamount = (currentprice - baseprice) * line.quantity;

      console.error(`Current Price: ${JSON.stringify(currentprice)}`);
      console.error(`Base Price: ${JSON.stringify(baseprice)}`);
      console.error(`Discount Amount: ${JSON.stringify(discountamount)}`);

      return {
        targets: [
          {
            productVariant: {
              id: variant.id
            }
          }
        ],
        value: {
          fixedAmount: {
            amount: discountamount
          }
        }
      };
    });

  if (!discounts.length) {
    console.error("No cart lines qualify for volume discount.");
    return EMPTY_DISCOUNT;
  }

  return {
    discounts,
    discountApplicationStrategy: DiscountApplicationStrategy.All
  };
};

 

 

 

This is the expected outcome:

benjamin_h_0-1721074147063.png

But if the same variant exists on another line, the applied discount amount is split amongst the additional lines and therefore doesn't fully apply to either line:

benjamin_h_1-1721074223687.png

My first thought was to change the returned target to cartLine: { id: line.id } as specified in the 'build discount function' example documentation:

benjamin_h_2-1721074780620.png

But that only generates the following error message and applies no discounts to any line:

[
  {
    "path": [
      "discounts",
      0,
      "targets",
      0
    ],
    "explanation": "Expected one of valid values: productVariant. Got: cartLine"
  },
  {
    "path": [
      "discounts",
      1,
      "targets",
      0
    ],
    "explanation": "Expected one of valid values: productVariant. Got: cartLine"
  },
  {
    "path": [
      "discounts",
      2,
      "targets",
      0
    ],
    "explanation": "Expected one of valid values: productVariant. Got: cartLine"
  }
]

Any insight or workarounds would be much appreciated.

 

 

Accepted Solution (1)

Jonathan_Harlap
Shopify Staff
4 1 3

This is an accepted solution.

 

Hi! Can you clarify what you are trying to achieve? Is it a fixed amount discount to apply to each quantity of the given product variant, or a fixed quantity that should be applied per line? If the former, take a look at the `appliesToEach` property of FixedAmount.

 

As for CartLineTarget not working - can you verify you're using API 2024-07 or newer? The error message makes me think you might be using 2024-04, which didn't include support for cart line targeting. I'm assuming that the cart line code you showed continues to build a complete FunctionRunResult that uses the targets array for a single discount proposal, right?

 

Cheers,

Jonathan

View solution in original post

Replies 4 (4)

mwade9
Shopify Partner
4 0 2

Experiencing the same issue.

Jonathan_Harlap
Shopify Staff
4 1 3

This is an accepted solution.

 

Hi! Can you clarify what you are trying to achieve? Is it a fixed amount discount to apply to each quantity of the given product variant, or a fixed quantity that should be applied per line? If the former, take a look at the `appliesToEach` property of FixedAmount.

 

As for CartLineTarget not working - can you verify you're using API 2024-07 or newer? The error message makes me think you might be using 2024-04, which didn't include support for cart line targeting. I'm assuming that the cart line code you showed continues to build a complete FunctionRunResult that uses the targets array for a single discount proposal, right?

 

Cheers,

Jonathan

benjamin_h
Shopify Partner
2 0 2

Thanks for your reply Jonathan. Ideally we'd like to target CartLines rather than productVariants because different lines of the same product variant might get a different discount amount depending on personalization selected.

 

I believe I was on 2024-07, and just switched to 2024-10 to test that with the same result. Can you confirm the correct procedure for switching the api version? I'm setting it within the app configuration in the Shopify Partners UI and in shopify.app.toml where I save and rerun 'shopify app dev' from the CLI.

😁Just realized I need to set in shopify.extension.toml, that has resolved the issue with targeting CartLines. 

Jonathan_Harlap
Shopify Staff
4 1 3

Happy to hear it! Cheers 🙂