1

I need to modify the query of the orders in the grid of the backend by representative attribute (custom attribute).

I get the following error:

Item (Magento\Framework\View\Element\UiComponent\DataProvider\Document) with the same ID "2" already exists.

DataProvider: (applyDealerFilter() method)

class DataProviderCollectionFactory
{
    /** @var mixed */
    protected $_requestName;

    /** @var  CollectionModifier */
    protected $_collectionModifier;

    /** @var  PermHelper */
    protected $_permHelper;

    /** @var DealerOrderCollectionFactory  */
    protected $_dealerOrderCollectionFactory;

    /** @var DealerCustomerCollectionFactory  */
    protected $_dealerCustomerCollectionFactory;

    /** @var Scope Config  */
    protected $_scopeConfig;

    /**
     * @param PermHelper $permHelper
     */
    public function __construct(
        CollectionModifier $collectionModifier,
        PermHelper $permHelper,
        DealerCustomerCollectionFactory $dealerCustomerCollectionFactory,
        DealerOrderCollectionFactory $dealerOrderCollectionFactory
    ) {
        $this->_collectionModifier = $collectionModifier;
        $this->_permHelper = $permHelper;
        $this->_dealerCustomerCollectionFactory = $dealerCustomerCollectionFactory;
        $this->_dealerOrderCollectionFactory = $dealerOrderCollectionFactory;
    }

    /**
     * @param CollectionFactory $collectionFactory
     * @param $requestName
     * @return array
     */
    public function beforeGetReport(
        CollectionFactory $collectionFactory,
        $requestName
    ){
        $this->_requestName = $requestName;
        return [$requestName];
    }

    /**
     * @param CollectionFactory $collectionFactory
     * @param AbstractCollection $collection
     * @return AbstractCollection
     * @throws \Exception
     */
    public function afterGetReport(
        CollectionFactory $collectionFactory,
        $collection
    ){
        if ($this->_permHelper->isAllowAllCustomersAndOrders()) {
            return $collection;
        }

        if (
            ($this->_collectionModifier->isOrderDataSource($this->_requestName)) &&
            $this->_permHelper->isBackendDealer()
        ){ //if order based collections
            $this->_collectionModifier->applyDealerFilter(
                $this->_permHelper->getBackendDealer()->getId(),
                $collection,
                $this->_dealerOrderCollectionFactory,
                'entity_id',
                'order_id'
            );
        } else if (
            (
                $this->_collectionModifier->isInvoiceDataSource($this->_requestName) ||
                $this->_collectionModifier->isShipmentDataSource($this->_requestName) ||
                $this->_collectionModifier->isCreditMemoDataSource($this->_requestName)
            ) &&
            $this->_permHelper->isBackendDealer()
        ) {
            $this->_collectionModifier->applyDealerFilter(
                $this->_permHelper->getBackendDealer()->getId(),
                $collection,
                $this->_dealerOrderCollectionFactory,
                'order_id',
                'order_id'
            );
        } else if (
            ($this->_collectionModifier->isCustomerDataSource($this->_requestName)) &&
            $this->_permHelper->isBackendDealer()
        ){ //if customer based collections
            $this->_collectionModifier->applyDealerFilter(
                $this->_permHelper->getBackendDealer()->getId(),
                $collection,
                $this->_dealerCustomerCollectionFactory,
                'entity_id',
                'customer_id'
            );
        }

        return $collection;
    }
}

Where the filter with joins is applied:

class CollectionModifier extends \Amasty\Perm\Helper\CollectionModifier
{
    /**
     * Filter collection by dealer
     * @param $value
     * @param AbstractCollection $collection
     * @param $factory
     * @param string $primaryKey
     * @param string $foreignKey
     * @param string $filterPostfix
     * @throws \Zend_Db_Select_Exception
     */
    public function applyDealerFilter(
        $value,
        AbstractCollection $collection,
        $factory,
        $primaryKey = 'entity_id',
        $foreignKey = 'entity_id',
        $filterPostfix = '_filter'
    ){

        $collection->getSelect()->join(
            ['ce' => $collection->getTable('customer_entity')],
            'ce.email = main_table.customer_email'
        )->join(
            ['cet' => $collection->getTable('customer_entity_text')],
            'cet.entity_id = ce.entity_id'
        )->join(
            ['ea' => $collection->getTable('eav_attribute')],
            'ea.attribute_id = cet.attribute_id'
        )->where(
            'ea.attribute_code = \'mod_dealers\''
        )->where(
            'cet.value like \'%' . $value . '%\''
        );


        /**
        here I have the error ID:
          Item (Magento\Framework\View\Element\UiComponent\DataProvider\Document) with the same ID "2" already exists.
        */
        var_dump($collection->toArray()); die("stop"); 

   }
}
3

Magento can not process more than two equal fields internally.

The solution is to make a where IN:

    $collection->getSelect()->where(
        ' main_table.entity_id IN (
                SELECT DISTINCT 
                so.entity_id
                FROM ' . $collection->getMainTable() . ' so
                INNER JOIN customer_entity ce on ce.email = so.customer_email
                INNER JOIN customer_entity_text cet on cet.entity_id = ce.entity_id
                INNER JOIN eav_attribute ea on ea.attribute_id = cet.attribute_id
                WHERE ea.attribute_code = \'mod_dealers\' 
                AND FIND_IN_SET(\'' . $value . '\', cet.value)
                )'
    );

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.