3

I have added to custom module to add catalog price rule condition. how to Add Rule Condition in My custom module, I have also added Rule file and Condition.

$renderer = $this->_rendererFieldset->setTemplate('Emipro_Seo::promo/fieldset.phtml')->setNewChildUrl($this->getUrl('catalog_rule/promo_catalog/newConditionHtml/form/rule_conditions_fieldset'));
        $fieldset = $form->addFieldset(
            'conditions_fieldset',
            ['legend' => __('Conditions (don\'t add conditions if rule is applied to all products)')]
        )->setRenderer($renderer);

        $fieldset->addField(
            'conditions',
            'text',
            ['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions'), 'required' => true]
        )->setRule(
            $model
        )->setRenderer(
            $this->_conditions
        );
0

2 Answers 2

2

Setep: 1. Add this file in Block folder

Vender\Module\Block\Adminhtml\Index\Edit\Tab

namespace Vender\Module\Block\Adminhtml\Index\Edit\Tab;

use Magento\Framework\App\ObjectManager;
use Magento\Backend\Block\Widget\Form\Generic;
use Magento\Backend\Block\Widget\Tab\TabInterface;

class Conditions extends Generic implements TabInterface
{
    /**
     * Core registry
     *
     * @var \Magento\Backend\Block\Widget\Form\Renderer\Fieldset
     */
    protected $_rendererFieldset;

    /**
     * @var \Magento\Rule\Block\Conditions
     */
    protected $_conditions;

    private $ruleFactory;

    /**
     * Initialize dependencies.
     *
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\Data\FormFactory $formFactory
     * @param \Magento\Rule\Block\Conditions $conditions
     * @param \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Rule\Block\Conditions $conditions,
        \Magento\Backend\Block\Widget\Form\Renderer\Fieldset $rendererFieldset,
        array $data = []
    ) {
        $this->_rendererFieldset = $rendererFieldset;
        $this->_conditions = $conditions;
        parent::__construct($context, $registry, $formFactory, $data);
    }


    private function getRuleFactory()
    {
        if ($this->ruleFactory === null) {
            $this->ruleFactory = ObjectManager::getInstance()->get('Magento\CatalogRule\Model\RuleFactory');
        }
        return $this->ruleFactory;
    }

    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function getTabClass()
    {
        return null;
    }



    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function getTabLabel()
    {
        return __('Conditions');
    }

    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function getTabTitle()
    {
        return __('Conditions');
    }

    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function canShowTab()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     * @codeCoverageIgnore
     */
    public function isHidden()
    {
        return false;
    }

    protected function _prepareForm()
    {
        $model = $this->_coreRegistry->registry('\Magento\CatalogRule\Controller\RegistryConstants::CURRENT_CATALOG_RULE_ID');

        if (!$model) {
            $id = $this->getRequest()->getParam('rule_id');
            $model = $this->getRuleFactory()->create();
            $model->load($id);
        }
        $fieldsetId = 'conditions_fieldset';
        $formName = 'catalog_rule_form';

        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();
        $form->setHtmlIdPrefix('rule_');

        $newChildUrl = $this->getUrl(
            'catalog_rule/promo_catalog/newConditionHtml/form/' . $model->getConditionsFieldSetId($formName),
            ['form_namespace' => $formName]
        );

        $renderer = $this->_rendererFieldset->setTemplate('Magento_CatalogRule::promo/fieldset.phtml')
                            ->setNewChildUrl($newChildUrl)
                            ->setFieldSetId($model->getConditionsFieldSetId($formName));

        $fieldset = $form->addFieldset(
            $fieldsetId,
            [
                'legend' => __(
                    'Apply the rule only if the following conditions are met (leave blank for all products).'
                )
            ]
        )->setRenderer(
            $renderer
        );


        $fieldset->addField(
            'conditions',
            'text',
            ['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions')]
        )->setRule(
            $model
        )->setRenderer(
            $this->_conditions
        );

        $form->setValues($model->getData());
        $this->setConditionFormName($model->getConditions(), $formName);
        $this->setForm($form);

        return parent::_prepareForm();
    }

}

Step: 2 Add this code in layout edit file

frontendname_index_edit.xml

<referenceContainer name="left">
        <block class="Vender\Module\Block\Adminhtml\Chartlist\Edit\Tabs" name="vender_module_edit_tabs">
            <block class="Vender\Module\Block\Adminhtml\Chartlist\Edit\Tab\Conditions" name="vender_module_tab_conditions"/>
            <action method="addTab">
                <argument name="name" xsi:type="string">conditions_section</argument>
                <argument name="block" xsi:type="string">vender_module_tab_conditions</argument>
            </action>
        </block>
    </referenceContainer>
13
  • Thankx You i have try this way ... thank You.. :)
    – user52726
    Commented Jun 1, 2017 at 6:58
  • brother i have try this way but can't disply Condition and all page is black only disply magento header .. :)
    – user52726
    Commented Jun 1, 2017 at 7:07
  • 1
    Can You send me your Files. Commented Jun 1, 2017 at 7:08
  • i am add your code only change vendor name and module name..
    – user52726
    Commented Jun 1, 2017 at 7:14
  • and i have add TAB.php file added tab for condition
    – user52726
    Commented Jun 1, 2017 at 7:14
1

Follow Below Steps:

Step-1: Create registration.php at app/code/VendoreName/AddConditionFiled

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'VendoreName_AddConditionFiled',
    __DIR__
);

Step-2: Create module.xml at app/code/VendoreName/AddConditionFiled/etc

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="VendoreName_AddConditionFiled" setup_version="1.0.1">
        <sequence>
           <module name="Magento_Checkout"></module>
           <module name="Magento_Catalog"></module>
       </sequence>
    </module>
</config>

Step-3: Create InstallSchema.php at app/code/VendoreName/AddConditionFiled/Setup

<?php

namespace VendoreName\AddConditionFiled\Setup;

use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class InstallSchema implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        if (!$installer->tableExists('VendoreName_custom_condition')) {
            $tableName = $installer->getTable('VendoreName_custom_condition');
            $table = $installer->getConnection()
                ->newTable($tableName)
                ->addColumn(
                    'rule_id',
                    Table::TYPE_INTEGER,
                    10,
                    [
                        'identity' => true,
                        'nullable' => false,
                        'primary' => true,
                    ],
                    'Rule ID'
                )
                ->addColumn(
                    'rule_status',
                    Table::TYPE_INTEGER,
                    null,
                    [
                        'nullable' => true,
                        'default' => null,
                    ],
                    'Rule Status'
                )
                ->addColumn(
                    'rule_name',
                    Table::TYPE_TEXT,
                    255,
                    [
                        'nullable' => true,
                        'default' => null,
                    ],
                    'Rule Name'
                )
                ->addColumn(
                    'conditions_serialized',
                    Table::TYPE_TEXT,
                    '2M',
                    [],
                    'Conditions Serialized'
                )
                ->addColumn(
                    'actions_serialized',
                    Table::TYPE_TEXT,
                    '2M',
                    [],
                    'Actions Serialized'
                )
                ->addColumn(
                    'create_date',
                    \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
                    null,
                    [
                        'nullable' => false,
                        'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT,
                    ],
                    'Create Date Time'
                )
                ->setComment('VendoreName Demo For Condition Field')
                ->setOption('type', 'InnoDB')
                ->setOption('charset', 'utf8');
            $installer->getConnection()->createTable($table);
        }
        $installer->endSetup();
    }
}

Here conditions_serialized and actions_serialized are used to store condition field value. So you must be add into you table. After creating table we add resource model and collection. Our Model name is CustomCondition.

Step-4: Create CustomCondition.php at app/code/VendoreName/AddConditionFiled/Model

<?php

namespace VendoreName\AddConditionFiled\Model;

use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition as CustomConditionResourceModel;
use Magento\Quote\Model\Quote\Address;
use Magento\Rule\Model\AbstractModel;

class CustomCondition extends AbstractModel
{
    protected $_eventPrefix = 'VendoreName_addconditionfiled';
    protected $_eventObject = 'rule';
    protected $condCombineFactory;
    protected $condProdCombineF;
    protected $validatedAddresses = [];
    protected $_selectProductIds;
    protected $_displayProductIds;

    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\CatalogRule\Model\Rule\Condition\CombineFactory $condCombineFactory,
        \Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory $condProdCombineF,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this->condCombineFactory = $condCombineFactory;
        $this->condProdCombineF = $condProdCombineF;
        parent::__construct($context, $registry, $formFactory, $localeDate, $resource, $resourceCollection, $data);
    }

    protected function _construct()
    {
        parent::_construct();
        $this->_init(CustomConditionResourceModel::class);
        $this->setIdFieldName('rule_id');
    }

    public function getConditionsInstance()
    {
        return $this->condCombineFactory->create();
    }

    public function getActionsInstance()
    {
        return $this->condCombineFactory->create();
    }

    public function hasIsValidForAddress($address)
    {
        $addressId = $this->_getAddressId($address);
        return isset($this->validatedAddresses[$addressId]) ? true : false;
    }

    public function setIsValidForAddress($address, $validationResult)
    {
        $addressId = $this->_getAddressId($address);
        $this->validatedAddresses[$addressId] = $validationResult;
        return $this;
    }

    public function getIsValidForAddress($address)
    {
        $addressId = $this->_getAddressId($address);
        return isset($this->validatedAddresses[$addressId]) ? $this->validatedAddresses[$addressId] : false;
    }

    private function _getAddressId($address)
    {
        if ($address instanceof Address) {
            return $address->getId();
        }
        return $address;
    }

    public function getConditionsFieldSetId($formName = '')
    {
        return $formName . 'rule_conditions_fieldset_' . $this->getId();
    }

    public function getActionFieldSetId($formName = '')
    {
        return $formName . 'rule_actions_fieldset_' . $this->getId();
    }

    public function getMatchProductIds()
    {
        $productCollection = \Magento\Framework\App\ObjectManager::getInstance()->create(
            '\Magento\Catalog\Model\ResourceModel\Product\Collection'
        );
        $productFactory = \Magento\Framework\App\ObjectManager::getInstance()->create(
            '\Magento\Catalog\Model\ProductFactory'
        );
        $this->_selectProductIds = [];
        $this->setCollectedAttributes([]);
        $this->getConditions()->collectValidatedAttributes($productCollection);
        \Magento\Framework\App\ObjectManager::getInstance()->create(
            '\Magento\Framework\Model\ResourceModel\Iterator'
        )->walk(
            $productCollection->getSelect(),
            [[$this, 'callbackValidateProductCondition']],
            [
                'attributes' => $this->getCollectedAttributes(),
                'product' => $productFactory->create(),
            ]
        );
        return $this->_selectProductIds;
    }

    public function callbackValidateProductCondition($args)
    {
        $product = clone $args['product'];
        $product->setData($args['row']);
        $websites = $this->_getWebsitesMap();
        foreach ($websites as $websiteId => $defaultStoreId) {
            $product->setStoreId($defaultStoreId);
            if ($this->getConditions()->validate($product)) {
                $this->_selectProductIds[] = $product->getId();
            }
        }
    }

    protected function _getWebsitesMap()
    {
        $map = [];
        $websites = \Magento\Framework\App\ObjectManager::getInstance()->create(
            '\Magento\Store\Model\StoreManagerInterface'
        )->getWebsites();
        foreach ($websites as $website) {
            if ($website->getDefaultStore() === null) {
                continue;
            }
            $map[$website->getId()] = $website->getDefaultStore()->getId();
        }
        return $map;
    }
}

Step-5: Create CustomCondition.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel

<?php

namespace VendoreName\AddConditionFiled\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class CustomCondition extends AbstractDb
{
    protected function _construct()
    {
        $this->_init('VendoreName_custom_condition', 'rule_id');
    }
}

Step-6: Create Collection.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel/CustomCondition

<?php

namespace VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition;

use VendoreName\AddConditionFiled\Model\CustomCondition as CustomConditionModel;
use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition as CustomConditionResourceModel;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    protected function _construct()
    {
        $this->_init(
            CustomConditionModel::class,
            CustomConditionResourceModel::class
        );
    }
}

Step-7: Create Collection.php at app/code/VendoreName/AddConditionFiled/Model/ResourceModel/CustomCondition/Grid

<?php

namespace VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid;

use VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Collection as CustomConditionCollection;
use Magento\Framework\View\Element\UiComponent\DataProvider\Document as CustomConditionModel;

class Collection extends CustomConditionCollection implements \Magento\Framework\Api\Search\SearchResultInterface
{
    protected $aggregations;

    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        $mainTable,
        $eventPrefix,
        $eventObject,
        $resourceModel,
        $model = CustomConditionModel::class,
        $connection = null,
        \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
    ) {
        parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
        $this->_eventPrefix = $eventPrefix;
        $this->_eventObject = $eventObject;
        $this->_init($model, $resourceModel);
        $this->setMainTable($mainTable);
    }

    public function getAggregations()
    {
        return $this->aggregations;
    }

    public function setAggregations($aggregations)
    {
        $this->aggregations = $aggregations;
    }

    public function getAllIds($limit = null, $offset = null)
    {
        return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
    }

    public function getSearchCriteria()
    {
        return null;
    }

    public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
    {
        return $this;
    }

    public function getTotalCount()
    {
        return $this->getSize();
    }

    public function setTotalCount($totalCount)
    {
        return $this;
    }

    public function setItems(array $items = null)
    {
        return $this;
    }
}

Step-8: Create di.xml at app/code/VendoreName/AddConditionFiled/etc

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">

    <virtualType name="VendoreNameAddConditionFiledFilterPool"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool">
        <arguments>
            <argument name="appliers" xsi:type="array">
                <item name="regular" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\RegularFilter</item>
                <item name="fulltext" xsi:type="object">Magento\Framework\View\Element\UiComponent\DataProvider\FulltextFilter</item>
            </argument>
        </arguments>
    </virtualType>

    <virtualType name="VendoreNameAddConditionFiledFilterPool"
                 type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider">
        <arguments>
            <argument name="collection" xsi:type="object" shared="false">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Collection</argument>
            <argument name="filterPool" xsi:type="object" shared="false">VendoreNameAddConditionFiledFilterPool</argument>
        </arguments>
    </virtualType>

    <type name="VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid\Collection">
        <arguments>
            <argument name="mainTable" xsi:type="string">VendoreName_custom_condition</argument>
            <argument name="eventPrefix" xsi:type="string">VendoreName_custom_condition_grid_collection</argument>
            <argument name="eventObject" xsi:type="string">VendoreName_custom_condition_grid_collection</argument>
            <argument name="resourceModel" xsi:type="string">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition</argument>
        </arguments>
    </type>

    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
        <arguments>
            <argument name="collections" xsi:type="array">
                <item name="custom_condition_listing_data_source" xsi:type="string">VendoreName\AddConditionFiled\Model\ResourceModel\CustomCondition\Grid\Collection</item>
            </argument>
        </arguments>

    </type>
</config>

Step-9: Create routes.xml at app/code/VendoreName/AddConditionFiled/etc/adminhtml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="admin">
        <route id="addconditionfiled" frontName="addconditionfiled">
            <module name="VendoreName_AddConditionFiled" before="Magento_Backend"/>
        </route>
    </router>
</config>

Step-10: Create Index.php at app/code/VendoreName/AddConditionFiled/Controller/Adminhtml/Index

<?php

namespace VendoreName\AddConditionFiled\Controller\Adminhtml\Index;

class Index extends \Magento\Backend\App\Action
{
    protected $resultPageFactory;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    public function execute()
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->getConfig()->getTitle()->prepend(__('Add Rules'));
        return $resultPage;
    }
}

Step-11: Create menu.xml at app/code/VendoreName/AddConditionFiled/etc/adminhtml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Magento/Backend/etc/menu.xsd">
   <menu>
        <add id="VendoreName_AddConditionFiled::VendoreName_addconditionfiled"
             title="VendoreName - Add Condition Field"
             translate="title"
             module="VendoreName_AddConditionFiled"
             sortOrder="10"
             parent="Magento_Backend::marketing"
             resource="VendoreName_AddConditionFiled::VendoreName_addconditionfiled" />

        <add id="VendoreName_AddConditionFiled::menu"
             title="Add Rules"
             module="VendoreName_AddConditionFiled"
             sortOrder="100"
             parent="VendoreName_AddConditionFiled::VendoreName_addconditionfiled"
             action="addconditionfiled/index/index"
             resource="VendoreName_AddConditionFiled::menu"/>
    </menu>
</config>

Click Here For Part 2

Click Here For Part 3

Check condition with products in Magento 2