Edit: originally this question was just about sales/order
objects but I've found an identical problem with sales/quote
objects too, so I'm editing it to include that.
I also added a TL;DR at the bottom which might be clearer for some people.
I'm trying to get information on the items from an order/quote, but have found that using $item->getSku()
is not very intuitive.
It always returns the child SKU, even if I'm running it inside a getAllVisibleItems()
loop (as opposed to just getAllItems()
).
The SKU it returns is different from $item->getProduct()->getSku()
.
When called inside getAllVisibleItems()
I would expect $item->getSku()
to return the parent product's SKU and not the child SKU (because the parent is the one which is visible).
Edit: I've discovered an even more problematic issue. When I loop on a sales/quote
collection instead of sales/order
, the $item->getProduct()->getSku()
call doesn't even return the correct (parent) SKU. It still returns the child-level SKU which is wrong. In order to get the correct parent-level SKU, I have to actually fully load the product (see the second block of code below).
Why is this happening?
Here's my code:
For sales/order collections:
<?php
$order = Mage::getModel("sales/order")->loadByIncrementId("123456");
foreach($order->getAllVisibleItems() as $orderItem) {
echo "Item SKU => " . $orderItem->getSku();
echo "Product SKU => " . $orderItem->getProduct()->getSku();
}
foreach($order->getAllItems() as $orderItem) {
echo "Item SKU => " . $orderItem->getSku();
echo "Product SKU => " . $orderItem->getProduct()->getSku();
}
// Output
getAllVisibleItems:
Item SKU => SHOE1-SIZE5 // Parent product - misleading item SKU
Product SKU => SHOE1
Item SKU => SHOE2-SIZE4 // Parent product - misleading item SKU
Product SKU => SHOE2
getAllItems:
Item SKU => SHOE1-SIZE5 // Parent product - misleading item SKU
Product SKU => SHOE1
Item SKU => SHOE1-SIZE5 // Child product - correct item SKU
Product SKU => SHOE1-SIZE5
Item SKU => SHOE2-SIZE4 // Parent product - misleading item SKU
Product SKU => SHOE2
Item SKU => SHOE2-SIZE4 // Child product - correct item SKU
Product SKU => SHOE2-SIZE4
For sales/quote collections:
$quote = Mage::getModel("sales/quote")->load("98765");
foreach($quote->getAllVisibleItems() as $quoteItem) {
echo "Item SKU => " . $quoteItem->getSku();
echo "Product SKU => " . $quoteItem->getProduct()->getSku();
echo "Fully Loaded Product SKU => " . Mage::getModel("catalog/product")->load($quoteItem->getProduct()->getId())->getSku();
}
foreach($quote->getAllItems() as $quoteItem) {
echo "Item SKU => " . $quoteItem->getSku();
echo "Product SKU => " . $quoteItem->getProduct()->getSku();
echo "Fully Loaded Product SKU => " . Mage::getModel("catalog/product")->load($quoteItem->getProduct()->getId())->getSku();
}
// Output
getAllVisibleItems:
Item SKU => SHOE1-SIZE5 // The child SKU (wrong)
Product SKU => SHOE1-SIZE5 // Different behaviour than sales/order object
Fully Loaded Product SKU => SHOE1 // The parent SKU (correct)
Item SKU => SHOE2-SIZE4 // The child SKU (wrong)
Product SKU => SHOE2-SIZE4 // Different behaviour than sales/order object
Fully Loaded Product SKU => SHOE2 // The parent SKU (correct)
getAllItems:
Item SKU => SHOE1-SIZE5 // Parent product - misleading item SKU
Product SKU => SHOE1-SIZE5 // Misleading
Fully Loaded Product SKU => SHOE2 // Correct
Item SKU => SHOE1-SIZE5 // Child product - correct item SKU
Product SKU => SHOE1-SIZE5 // Correct
Fully Loaded Product SKU => SHOE1-SIZE5 // Correct
Item SKU => SHOE2-SIZE4 // Parent product - misleading item SKU
Product SKU => SHOE2-SIZE4 // Misleading
Fully Loaded Product SKU => SHOE2 // Correct
Item SKU => SHOE2-SIZE4 // Child product - correct item SKU
Product SKU => SHOE2-SIZE4 // Correct
Fully Loaded Product SKU => SHOE2-SIZE4 // Correct
TL;DR
The TL;DR of this post is: These two SKUs come out different. Why?
$cartItems = Mage::getSingleton('checkout/cart')->getQuote()->getAllVisibleItems();
foreach ($cartItems as $cartItem) {
// These two SKUs are different. Why?
echo $cartItem->getProduct()->getSku();
echo Mage::getModel("catalog/product")->load($cartItem->getProduct()->getId())->getSku();
}
$item->getSku()
gets the SKU stored at the time when the order/quote was created.$item->getProduct()->getSku()
first loads the product and then gets the SKU from that object, this could be a different one than the one in the$item
when it was changed after the product was edited for example.$item->getProduct()
returns the wrong SKU, but$item->getProduct->getId()
returns the correct ID.getSku()
.