Question

I created a custom price filter (without layered navigation). This function works great on simple products, but configurable products are filtered (maybe because they don't have a price?).

This is my function:

<?php namespace Silvan\Sidebar\Model\Plugin;

use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;

class SidebarFilter
{
    public function aroundAddFieldToFilter(ProductCollection $collection, \Closure $proceed, $fields, $condition = null)
    {
        if ($fields === 'category_ids') {

            $price  = isset($_GET[ 'price' ]) ? $_GET[ 'price' ] : false;

            if ($price && strpos($price, '-') !== false) {
                $price = explode('-', $price);
                $min   = isset($price[ 0 ]) ? $price[ 0 ] : 0;
                $max   = isset($price[ 1 ]) ? $price[ 1 ] : 9999999;

                $collection->addAttributeToFilter('price', ['gt' => $min]);
                $collection->addAttributeToFilter('price', ['lt' => $max]);
            }
        }

        return $fields ? $proceed($fields, $condition) : $collection;
    }
}

I tried using min_price and max_price, but these attributes are ignored in the filter.

Was it helpful?

Solution

Your code did not for simple products too (because it not include data from special price, tear price, required options, catalog price rules).

Magento using price index mechanism to pre-calculate price for a product. See catalog_product_index_price table. The field min_price contains the minimal possible price for product and layered navigation use this field for filtering.

So, try replace in your code

$collection->addAttributeToFilter('price', ['gt' => $min]);
$collection->addAttributeToFilter('price', ['lt' => $max]);

on

$collection->addFieldToFilter('price', ['from' => $min, 'to' => $max]);

OTHER TIPS

Try this code, it filters on min_price range used by configurable products:

class Related extends \Magento\Framework\View\Element\Template
{
  public function __construct(
    \Magento\Backend\Block\Template\Context $context,
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
    \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
    \Magento\Catalog\Model\Product\Visibility $productVisibility,
    \Magento\Framework\Registry $registry,
    array $data = []
  )
  {
    $this->_productCollectionFactory = $productCollectionFactory;
    $this->productStatus = $productStatus;
    $this->productVisibility = $productVisibility;
    $this->_registry = $registry;
    parent::__construct($context, $data);
  }

  public function getProductCollection()
  {
    try {

      $product = $this->_registry->registry('current_product');

      $range_percentage = 35;
      $price_temp = round($product->getFinalPrice() / 100 * $range_percentage);
      $price_from = $product->getFinalPrice() - $price_temp;
      $price_to = $product->getFinalPrice() + $price_temp;

      $categories = $product->getCategoryIds();

      $collection = $this->_productCollectionFactory->create();
      $collection->addAttributeToSelect('*')
        ->addCategoriesFilter(['in' => $categories])
        ->addPriceDataFieldFilter('%s >= %s', ['min_price', $price_from])
        ->addPriceDataFieldFilter('%s <= %s', ['min_price', $price_to])
        ->addMinimalPrice()
        ->addAttributeToFilter('entity_id', ['neq' => $product->getId()])
        ->addAttributeToFilter('status', ['in' => $this->productStatus->getVisibleStatusIds()])
        ->setVisibility($this->productVisibility->getVisibleInSiteIds())
        ->setPageSize(5);

      return $collection;

    } catch (\Exception $e) {

      var_dump($e->getMessage());
    }
  }
}

Configurable products are filtered (maybe because they don't have a price?). > You're right.

I have exactly the same issue when filtering quantity (qty).

Configurable products quantity is 0.

I don't think the team who designed Magento 2 handled this feature to be able to filter by configurable products children attributes.

We will have to analyze the vendor source code to figure out if they did it somewhere somehow.

Another possible fix would be to set price/quantity of configurable products manually by fetching its children attributes. Maybe a custom script/command we could then put into a cron after each stock update/import.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top