5

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?

1 Answer 1

1

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
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.