Question

This is my observer and its updating my custom attribute every time when I save attributes on catalog_product_attribute_update_before event.

namespace MyVendor\MyModule\Observer;


class TotalCalcScore implements \Magento\Framework\Event\ObserverInterface
{

    protected $_product;


    public function __construct(
        \Magento\Catalog\Model\ProductFactory $product
    ) {
        $this->_product = $product;
    }


    public function execute(
        \Magento\Framework\Event\Observer $observer
    )
    {   
   $productIds = $observer->getProductIds();
    foreach($productIds as $id){
    $product = $this->_product->create()->load($id);

            if($product->getId()){


                // attribute_first_count
                $value_offirst_count = $product->getattribute_first_count();
                // attribute_second_count
                $value_offsecond_score = $product->getattribute_second_count();
               // attribute_calculated_count
                $value_calculated_score = $product->getattribute_calculated_count();



                // calculate
         $value_calculated_score = $value_offsecond_score + $value_offirst_count

                //save calculated value
                //$product->setCalculatedValue($value_calculated_score);
                //save to attribute_calculated_score 
                $product->setAttrCalculatedScore($value_calculated_score);

                $product->save();
}

    }
}

But what should I do if I want to move this to Model and run this like cron job or indexation? Or is it better to run this before indexation like observer. (but I need load collection in that case?)

UPDATE:

I created mview.xml and indexer.xml and this is my Model/Review/Indexer/Review.php but still is not working corectly

class Review implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
    /**
     * Execute full indexation
     *
     * @return void
     */
   public function executeFull()
    {
        // TODO: Implement executeFull() method.
    }
    /**
     * Execute partial indexation by ID list
     *
     * @param int[] $ids
     *
     * @return void
     */
    public function executeList(array $ids)
    {
        // TODO: Implement executeList() method.
    }

    /**
     * Execute partial indexation by ID
     *
     * @param int $id
     *
     * @return void
     */
    public function executeRow($id)
    {
        // TODO: Implement executeRow() method.
    }


    /**
     * @var \Magento\Catalog\Api\Data\ProductInterfaceFactory
     */
    private $productFactory;
    /**
     * @var \Magento\Catalog\Api\ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * MyClass constructor
     *
     * @param \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory
     * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
     */
    protected $collectionFactory;




    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Catalog\Api\Data\ProductAttributeInterface $productAttribute,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory
    )
    {
        $this->productRepository = $productRepository;
        $this->collectionFactory = $collectionFactory;
        $this->collectionFactory = $productAttribute;
    }

 /**
     * Execute materialization on ids entities
     *
     * @param int[] $ids
     *
     * @return void
     * @api
     */

    public function execute($ids)
    {
      //  $post = $this->_postFactory->create();
       // $collection = $post->getCollection();
        // Use factory to create a new product collection
        $productCollection = $this->collectionFactory->create();
        // Apply filters here
        $productCollection->addAttributeToSelect('*');
        // Don't have to do this
        $productCollection->load();

        foreach($collection as $ids){
            $productCollection->addAttributeToSelect('*');
            // Don't have to do this
            // $productCollection->load();

            foreach ($productCollection as $product) {
                // attribute_first_count
                $value_offirst_count = $product->getattribute_first_count();
                // attribute_second_count
                $value_offsecond_score = $product->getattribute_second_count();
               // attribute_calculated_count
                $value_calculated_score = $product->getattribute_calculated_count();



                // calculate
         $value_calculated_score = $value_offsecond_score + $value_offirst_count

                //save calculated value
                //$product->setCalculatedValue($value_calculated_score);
                //save to attribute_calculated_score 
                $product->setAttrCalculatedScore($value_calculated_score);

                $product->save();
            }
        }
        exit();
        return $this->_pageFactory->create();
    }
}

after reindex : index has been rebuilt successfully in 00:00:00 but there is no change in atribute value

Maybe I should add this like a cron job and this above not make any sense?

Was it helpful?

Solution

I finished to set this like a cron job. I'm not sure is it proper way to do this.

I moved my function from observer to controller and changed my crontab.xml to use this controller.

    <job name="custom_cronjob" instance="MyVendor\MyModule\Controller\Calc" method="execute">
        <schedule>* * * * *</schedule>
    </job>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top