sortingshopware

Sorting by reference price in Shopware


From the official documentation https://developer.shopware.com/docs/guides/plugins/plugins/storefront/add-custom-sorting-product-listing.html it is clear enough how to add new custom sorting on PLP with Shopware. But how to implement sorting by the reference price? This value is not stored in the database but calculated on fly, thus it is not possible to provide a field parameter at $myCustomSorting->setFields().

For example, we have two products with gross prices 10.00 and 15.00 and these products have selling units 0.5 and 0.9 respectively (for m2 in pack). We want to sort products based on reference price per m2 10 / 0.5 = 20.00 and 15 / 0.9 = 16.67.


Solution

  • In the end, the problem was fixed with the following solution:

    class UnitPriceField extends CheapestPriceField
    {
        protected function getAccessorBuilderClass(): ?string
        {
            return UnitPriceFieldAccessorBuilder::class;
        }
    }
    
    class UnitPriceFieldAccessorBuilder extends CheapestPriceAccessorBuilder
    {
        public function buildAccessor(string $root, Field $field, Context $context, string $accessor): ?string
        {
            $price = parent::buildAccessor($root, $field, $context, 'cheapestPrice');
    
            return $price . ' * IFNULL(`product`.`reference_unit`, 1) / IFNULL(`product`.`purchase_unit`, 1)';
        }
    }
    
    class SalesChannelProductDefinition extends ShopwareSalesChannelProductDefinition
    {
        protected function defineFields(): FieldCollection
        {
            $fields = parent::defineFields();
    
            $fields->add(
                (new UnitPriceField('unit_price', 'unitPrice'))
                    ->addFlags(new Runtime())
            );
    
            return $fields;
        }
    }