4

In my Magento 2 extension I do calculate the product weight when the user adds an item to the cart.

My problem is that the weight I set gets overwritten at the checkout. Cause is the setProduct() function of Magento\Quote\Model\Quote\Item.php.

To prevent this I created a plugin:

Vendor\Module\Plugin\ItemModelPlugin.php

namespace Vendor\Module\Plugin;

use Magento\Quote\Model\Quote\Item as QuoteItem;

class ItemModelPlugin
{

    public function aroundSetProduct(QuoteItem $subject, \Closure $proceed, $product)
    {

        if($product->getData('isCalcWeight') == true)
        {
            $weight = $subject->getWeight();
            $result =  $proceed($product);
            $subject->setWeight($weight);
            $subject->save();

        }else {

            $result =  $proceed($product);

        }

        return $result;

    }
}

But two things don't work here.

$product->getData('isCalcWeight') and $subject->getWeight() always return NULL.

Note: The attribute "isCalcWeight" is a bool that is set to true/false depending on the fact if a custom weight is used or not.

Can someone help me out here?

UPDATE

Something to add is that I need to calculate my weight beforehand, because it is calculated with an ajax request which takes the chosen product options and returns the calculated price and weight for the product. Calculating this every time the product is set would makes things slow, unnecessarily complicated and possibly prone to bugs.

  • Not enough information. How do you calculate something for a product and save it in your extension. Remember that products aren't things you put in a cart. Products are the blueprints for things you put in your cart. It's probably better to store the weight on the cart object or the user's session and then apply it when the product is converted to item, so after setProduct() is called. – Melvyn Apr 20 '18 at 8:49
  • The weight is not stored in the product, it is stored in the quote item Magento\Quote\Model\Quote\Item – TrytoFly Apr 20 '18 at 9:47
  • Then... is possible that ajax request has not ended yet when your plugin executes? – Raul Sanchez Apr 20 '18 at 12:56
  • nope, the ajax request was executed in the product view and the value is already written into the table quote_item. The method returns NULL when the plugin is executed at the checkout. – TrytoFly Apr 20 '18 at 14:05
  • You should debug that request and look at the data store ($this->_data) for that product. It's possible the isCalcWeight attribute is simply not fetched or spelled slightly different. – Melvyn Apr 20 '18 at 14:56
0

Looking setProduct() method...

public function setProduct($product)
{
    if ($this->getQuote()) {
        $product->setStoreId($this->getQuote()->getStoreId());
        $product->setCustomerGroupId($this->getQuote()->getCustomerGroupId());
    }
    $this->setData('product', $product)
        ->setProductId($product->getId())
        ->setProductType($product->getTypeId())
        ->setSku($this->getProduct()->getSku())
        ->setName($product->getName())
        ->setWeight($this->getProduct()->getWeight())
        ->setTaxClassId($product->getTaxClassId())
        ->setBaseCost($product->getCost());

    $stockItem = $product->getExtensionAttributes()->getStockItem();
    $this->setIsQtyDecimal($stockItem ? $stockItem->getIsQtyDecimal() : false);

    $this->_eventManager->dispatch(
        'sales_quote_item_set_product',
        ['product' => $product, 'quote_item' => $this]
    );

    return $this;
}

Why not changing your plugin and making it for Magento\Catalog\Model\Product getWeight(), using the after approach?

Another way could use sales_quote_item_set_product event, to update QuoteItem weight value

I see both ways easier to get results than your around plugin

  • I can't use the after method, because I calculate the weight beforehand. See question update. – TrytoFly Apr 20 '18 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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