0

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?

0

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>

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.