0

Magento V2.4.1

We have created one attribute named "Test" with 2 values "test1" and "test2". We are required to automatically select the value "test2" when the product's quantity is less than 0 "test1" when the product's quantity is greater than 0 when we save the product in the admin. For that, we took the "catalog_product_save_after" event and created an observer. everything is working as excepted. when we save the product in the admin and if the quantity is greater than 0 then the "test1" will be automatically selected in that product and if the quantity is less than 0 then the "test2" will be automatically selected in that product.

Now we have nearly 2500 products in our store and we want to set either of the mentioned values for the "Test" attribute in all products. So we have tried to use "catalog_product_attribute_update_before" and created an observer for that event. now in the admin when we have selected multiple products(2 products) and clicked on "Update attribute" from the Mass action menu and then we have updated one other attribute and clicked on save. the other attribute which we have tried to update for multiple products is updated successfully but it seems the "Test" attribute didn't update as it should be.

I think the observer for the event "catalog_product_attribute_update_before" didn't get triggered at all.

I think the method update attributes in Magento\Catalog\Model\Product\Action is responsible for update attributes via the product mass action. So I tried to create the `around plugin for the mentioned method but that didn't work as well. Unfortunately, I can't share the code of the around plugin method.

  1. Using Event Observer:

app/code/Test/Module/etc/adminhtml/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_attribute_update_before">
        <observer name="change_inventory_mass_actions" instance="Test\Module\Observer\AttributeUpdateObserver" />
    </event>
</config>

app/code/Test/Module/Observer/AttributeUpdateObserver.php

<?php

namespace Test\Module\Observer;

use Magento\Framework\Event\ObserverInterface;

class AttributeUpdateObserver implements ObserverInterface
{  
    /**
     * @var LoggerInterface
     */
    private $loggerInterface;

    public function __construct(
        \Psr\Log\LoggerInterface $loggerInterface
    ) {
        $this->logger = $loggerInterface;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $logger = new \Zend\Log\Logger();
        $testLog = new \Zend\Log\Writer\Stream(BP.'/var/log/attr_observer.log');
        $logger->addWriter($testLog);
        $logger->info("Mass action event is called");
        try {
            $productIds = $observer->getProductIds();
            $attributes = $observer->getAttributesData();   
        } catch (\Execption $e) {
            $this->logger->info('Error : '.$e->getMessage());
        }
    }   
}

How can I create an observer that will trigger on Mass action save? or Is there any other way instead of an event observer?

1 Answer 1

1

Give try on the following solution. It is working well for me in a couple of projects.

File: app/code/Test/Module/etc/adminhtml/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <type name="Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save">
        <plugin name="TestModule::BulkProductSavePlugin"
                type="Test\Module\Plugin\Admin\BulkProductAttributeSavePlugin"
                sortOrder="1"
        />
    </type>
</config>

File: app/code/Test/Module/Plugin/Admin/BulkProductAttributeSavePlugin.php


<?php

namespace Test\Module\Plugin\Admin;

use Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute\Save;
use Magento\Catalog\Helper\Product\Edit\Action\Attribute;
use Zend\Log\Logger;
use Zend\Log\Writer\Stream;

class BulkProductAttributeSavePlugin
{

    /**
     * @var Attribute
     */
    private $attributeHelper;

    public function __construct(
        Attribute $attributeHelper
    )
    {
        $this->attributeHelper = $attributeHelper;
    }

    /**
     * @param Save $subject
     * @param $result
     *
     * @return mixed
     */
    public function afterExecute(
        Save $subject,
             $result
    )
    {
        try {
            $productIds = $this->attributeHelper->getProductIds();
            $storeId = $this->attributeHelper->getSelectedStoreId();
            if (empty($productIds)) {
                return $result;
            }

            $logger = new Logger();
            $testLog = new Stream(BP.'/var/log/attr_observer.log');
            $logger->addWriter($testLog);
            foreach ($productIds as $productId){
                $logger->info($productId);
            }


        } catch (\Exception $e) {
            return $result;
        }
        return $result;
    }
}


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.