My task is related to the smart categories. Smart categories are those which assign the products based on the rules.
Rules of categories can be
- Category A: Those products which quantity is more than 1000 should be assign to this category.
- Category B: Assign the products based on the brand of the product.
Magento 2 Enterprise provide us rules functionality after adding which we can achieve the above functionality. But we want to update category whenever any product full fill the rule then it should assign to rule related category.
Magento 2 Enterprise does not assign newly products which follow the rules automatically until we re-save the category. So i try to re-save the smart categories using cron. It's code is
class Category
{
/**
* @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
*/
protected $_categoryCollectionFactory;
/**
* @var \Magento\Catalog\Api\CategoryRepositoryInterface
*/
protected $_repository;
/**
* @var \Psr\Log\LoggerInterface
*/
protected $_logger;
/**
* @var \Magento\VisualMerchandiser\Model\Rules
*/
protected $_modelRulesFactory;
/**
* Index constructor. Here we are gettingthe logger for log. categorycollection to get all the categories and category repository to save the smart categories
* @param \Magento\Framework\App\Action\Context $context
* @param LoggerInterface $logger
* @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory
* @param \Magento\Catalog\Api\CategoryRepositoryInterface $repository
* @param RulesFactory $modelRulesFactory
*/
public function __construct(\Psr\Log\LoggerInterface $logger,
\Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
\Magento\Catalog\Api\CategoryRepositoryInterface $repository,
RulesFactory $modelRulesFactory) {
$this->_logger = $logger;
$this->_categoryCollectionFactory = $categoryCollectionFactory;
$this->_repository = $repository;
$this->_modelRulesFactory = $modelRulesFactory;
}
/**
* In this function we load all the categories and only save the smart categories so rules for products can apply and assign the new best seller products according to rules
*
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function execute() {
try{
$this->_logger->addDebug('Updating categories');
$categories = $this->_categoryCollectionFactory->create();
$categories->addAttributeToSelect('*');
$rulesModel = $this->_modelRulesFactory->create();
foreach ($categories as $category) {
$rule = $rulesModel->loadByCategory($category);
if ($rule->getId() && $rule->getIsActive()) {
$category->setStoreId(0);
$rule->setIsActive(1);
$this->_repository->save($category);
}
}
}catch (Exception $e){
$this->_logger->addDebug($e->getMessage());
}
}
}
The above code works very good with those rules which are using the rules based on the default attributes. For example if rule is quantity > 1000 here quantity is default attributes so those categories update very well. But if it is like Brand = 'Nike', then after execute the above code it's assigned products become 0.
Can you please help me why it is happening? Thank you very much.