Fetching simple product data from a quote item, based on a configurable product
-
05-10-2020 - |
Question
In my module I want to do some things if a product in the cart has a custom attribute 'servicepack'.
So by using the /etc/catalog_attributes.xml I exposed the property
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
<group name="quote_item">
<attribute name="servicepack"/>
</group>
</config>
Next, I added my logic.
/** @var /Magento\Quote\Model\Quote $quote */
$quoteItems = $quote->getItems();
foreach($quoteItems as $cartItem){
$product = $cartItem->getProduct(); //This is the configurable product
$simpleId= $product->getIdBySku($product->getSku());
/** @var ProductRepositoryInterface $this->productRepository */
$simpleProduct = $this->productRepository->getById($simpleId); //Seems overkill?
if($simpleProduct->getData('servicepack') == 123){ //This property is only on the simple product
// do stuff
}
}
I doubt this is the correct way to handle this situation.
The thing that confuses me:
The $cartItem
is a configurable product. My 'servicepack' attribute is only set on the simple product. So I need to get the simple product data. I solved this by getting the simple product id, and fetching the simple product from the ProductRepository
.
However, this seems inefficient, because it causes a db query for each product.
Question: Is it possible to get the simple product data without a database query?
For example: $product->getSimpleObject($product->getSku()); //Returns the $simpleProduct
Or would my solution be considered a decent way to handle things?
Solution
Question is a bit old but as I encountered the problem aswell now on Magento 2.3.5 I want to answer it.
It is easy but not obviously. You need to use $quote->getItemsCollection();
instead of $quote->getItems();
. This will give you a collection object with the parent AND child products. If you only need to consider the simple products, then change your code like this:
/** @var /Magento\Quote\Model\Quote $quote */
$quoteItems = $quote->getItemsCollection();
foreach($quoteItems as $cartItem){
if($cartItem->getProductType() !== 'simple') {
continue;
}
}
if($cartItem->getData('servicepack') == 123){ //This property is only on the simple product
// do stuff
}
}