Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cart Transform API - UpdateOperation doesn't change prices if MergeOperation is used also #470

Open
AncleMarvel opened this issue Mar 12, 2024 · 0 comments

Comments

@AncleMarvel
Copy link

Which template or example

Cart Transform API with customized bundles. API version 2024-01

Describe the bug

I tried to set up the following logic: merge some products with percentageDecrease e.g. 10% but don't apply 10% discount to a specific component in a bundle and set fixedPricePerUnit to its price - e.g. 9.99 $. In this case output is correct, it shows that given line items got price reduced by 9.99 in update objects and the merge object is also correct with decreasing 10% off.

But in the cart and on checkout page it shows price of the bundle as it would be without decreasing by 9.99. It applies 10% to the whole bundle but doesn't apply 9.99 $ off;

Based on the documentation, if you use the Update and Merge operations on the same cart line, then Shopify will apply both operations, since they do not directly conflict with each other. The Merge operation will merge multiple cart rows into one, while Update will change the properties of that merged row (such as price, image, or title). This is exactly what I was counting on when creating the logic described above. But this does not work as expected, using merge always creates a bundle with product prices without taking into account update operations.

If I don't use merge operation then update operations works as expected but in this case I don't have bundles :(

How I tried to make it work:

  • Use merge without any price percentageDecrease and use update for any operations with prices
  • Use merge with 10% percentageDecrease and use update prices for only those line items in the bundle which I need decrease by 9.99$
  • I also tried to change an order of operations execution (I thought that's an issue of the order)

Steps to reproduce

Use the merge operation and apply some price changes in the update operation you will see that price changes from update operation were not applied

Expected behavior

Using the merge operation and apply some price changes in the update operation - price changes from update operation will be applied together with the price changes from the merge operation

Environment

  • Operating system - Windows 11
  • Shopify CLI version - 3.56.3

Additional context

Add any other context about the problem here.
My client has this logic in his Shopify Scripts and we are trying to migrate to Functions API.

Here some examples of my code:

run.graphql:

query RunInput {
  cart {
    lines {
      id
      quantity
      bundleId: attribute(key: "_order_timestamp") {
        value
      }
      hasSpecificDiscount: attribute(key: "_has_specific_discount") {
        value
      }
      cost {
        amountPerQuantity {
          amount
        }
        totalAmount {
          amount
        }
      }
    }
  }
  presentmentCurrencyRate
}

run.js:

// @ts-check

// gid://shopify/ProductVariant/42013834969142
/**
 * @typedef {import("../generated/api").RunInput} RunInput
 * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
 */

/**
 * @type {FunctionRunResult}
 */
const NO_CHANGES = {
  operations: [],
};

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {

  const bundleDiscount = 10; // to get % devide by 100
  const specificDiscountAmount = 9.99 * input.presentmentCurrencyRate; // amount in euros
  const linesWithSpecificDiscount = [];
  const groupedItems = {};
  input.cart.lines.forEach((line) => {
    const bundleId = line.bundleId;
    if (bundleId && bundleId?.value) {
      if (!groupedItems[bundleId.value]) {
        groupedItems[bundleId.value] = [];
      }

      groupedItems[bundleId.value].push(line);

      if (line.hasSpecificDiscount) {
        linesWithSpecificDiscount.push({
          line: line,
          bundleDiscount: bundleDiscount, // discount applied to the bundle which must be excluded if it has specific discount
        });
      }
    }
  });

  return {
    operations: [
      ...linesWithSpecificDiscount.map((obj) => {

        const linePrice = {
          amount: +obj.line.cost.amountPerQuantity.amount,
          totalAmount: +obj.line.cost.totalAmount.amount,
        };

        return {
          update: {
            cartLineId: obj.line.id,
            price: {
              adjustment: {
                fixedPricePerUnit: {
                  amount: linePrice.totalAmount - specificDiscountAmount,
                }
              }
            }
          }
        }
      }),

      ...Object.values(groupedItems).map((group) => {
        const mergeOperation = {
          merge: {
            cartLines: group.map((line) => {

              return {
                cartLineId: line.id,
                quantity: line.quantity,
              };

            }),
            parentVariantId: 'gid://shopify/ProductVariant/42013834969142',

            title: "Mix-n-match",
            price: {
              percentageDecrease: {
                value: bundleDiscount
              }
            }
          }
        }

        return mergeOperation;
      })
    ]
  };
};

Input (STDIN):

{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/b28e53bf-df88-4c90-84dd-162d036da6a1",
        "quantity": 1,
        "bundleId": {
          "value": "1710265809875"
        },
        "hasSpecificDiscount": {
          "value": "true"
        },
        "cost": {
          "amountPerQuantity": {
            "amount": "11.99"
          },
          "totalAmount": {
            "amount": "11.99"
          }
        }
      },
      {
        "id": "gid://shopify/CartLine/ad70ddb8-164d-42db-bf33-ea7a16ba5973",
        "quantity": 1,
        "bundleId": {
          "value": "1710265809875"
        },
        "hasSpecificDiscount": null,
        "cost": {
          "amountPerQuantity": {
            "amount": "500.0"
          },
          "totalAmount": {
            "amount": "500.0"
          }
        }
      },
      {
        "id": "gid://shopify/CartLine/03f14223-10c9-4701-b0d6-d1f58a32170e",
        "quantity": 1,
        "bundleId": {
          "value": "1710265809875"
        },
        "hasSpecificDiscount": null,
        "cost": {
          "amountPerQuantity": {
            "amount": "1000.0"
          },
          "totalAmount": {
            "amount": "1000.0"
          }
        }
      }
    ]
  },
  "presentmentCurrencyRate": "1.0"
}

Output (STDOUT):

{
  "operations": [
    {
      "update": {
        "cartLineId": "gid://shopify/CartLine/b28e53bf-df88-4c90-84dd-162d036da6a1",
        "price": {
          "adjustment": {
            "fixedPricePerUnit": {
              "amount": 2
            }
          }
        }
      }
    },
    {
      "merge": {
        "cartLines": [
          {
            "cartLineId": "gid://shopify/CartLine/b28e53bf-df88-4c90-84dd-162d036da6a1",
            "quantity": 1
          },
          {
            "cartLineId": "gid://shopify/CartLine/ad70ddb8-164d-42db-bf33-ea7a16ba5973",
            "quantity": 1
          },
          {
            "cartLineId": "gid://shopify/CartLine/03f14223-10c9-4701-b0d6-d1f58a32170e",
            "quantity": 1
          }
        ],
        "parentVariantId": "gid://shopify/ProductVariant/42013834969142",
        "title": "Mix-n-match",
        "price": {
          "percentageDecrease": {
            "value": 10
          }
        }
      }
    }
  ]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant