'I'am trying to add new field of the product price attribute value (msrp, map ) on storefront

Here is the code i am trying to use

    -  '@add':  
            id: price_attribute_product_price
            parentId: product_view_specification
            blockType: product_prices
            options:
                label: visible

but it doesn't do anything! Am i missing something?



Solution 1:[1]

That's how we did it too, although ours is hard-coded to the RRP attribute but it's pretty easy to customize this.

Sharing our code as I think it's been asked quite a few times in the community before.

We created our own custom Price Provider:

namespace Aligent\BaseBundle\Provider;

use Oro\Bundle\CurrencyBundle\Entity\Price;
use Oro\Bundle\EntityBundle\ORM\DoctrineHelper;
use Oro\Bundle\PricingBundle\Entity\PriceAttributePriceList;
use Oro\Bundle\PricingBundle\Entity\PriceAttributeProductPrice;
use Oro\Bundle\PricingBundle\Provider\PriceAttributePricesProvider;
use Oro\Bundle\ProductBundle\Entity\Product;

/**
 * Makes the rrp price attribute available.
 * The rrp price attribute can be found in db table: oro_price_attribute_pl
 */
class RRPPriceProvider
{
    const PRICE_ATTRIBUTE = 'RRP';

    protected DoctrineHelper $doctrineHelper;
    protected PriceAttributePricesProvider $priceAttributePricesProvider;

    /**
     * @param DoctrineHelper $doctrineHelper
     * @param PriceAttributePricesProvider $priceAttributePricesProvider
     */
    public function __construct(
        DoctrineHelper $doctrineHelper,
        PriceAttributePricesProvider $priceAttributePricesProvider
    ) {
        $this->doctrineHelper = $doctrineHelper;
        $this->priceAttributePricesProvider = $priceAttributePricesProvider;
    }


    /**
     * Get RRP price with unit and currencies from custom Product Price Attribute Price List
     * @param Product $product
     * @return array
     */
    public function getRRPPriceWithUnitAndCurrencies(Product $product) : array
    {
        /** @var PriceAttributePriceList $rrpPriceList */
        $rrpPriceList = $this->getRRPAttributePriceList();

        return $this->priceAttributePricesProvider->getPricesWithUnitAndCurrencies($rrpPriceList, $product);
    }

    /**
     * Get RRP price from custom Product Price Attribute Price List
     * @param Product $product
     * @return Price|null
     */
    public function getRRPPrice(Product $product) : ?Price
    {
        /** @var PriceAttributePriceList $rrpPriceList */
        $rrpPriceList = $this->getRRPAttributePriceList();

        /** @var PriceAttributeProductPrice $priceAttributePrice */
        $priceAttributePrice = $this->doctrineHelper
            ->getEntityRepository(PriceAttributeProductPrice::class)
            ->findOneBy(['product' => $product, 'priceList' => $rrpPriceList]);

        return $priceAttributePrice?->getPrice();
    }

    /**
     * Gets just the RRP Price Attribute Price List
     * @return PriceAttributePriceList|null
     */
    protected function getRRPAttributePriceList() : PriceAttributePriceList
    {
        return $this->doctrineHelper->getEntityRepository(PriceAttributePriceList::class)->findOneBy([
            'name' => self::PRICE_ATTRIBUTE,
        ]);
    }
}

And then we have a Layout DataProvider to make this available in the layouts:


namespace Aligent\BaseBundle\Layout\DataProvider;

use Aligent\BaseBundle\Provider\RRPPriceProvider;
use Oro\Bundle\ProductBundle\Entity\Product;

class RRPPriceLayoutProvider
{
    protected RRPPriceProvider $rrpPriceProvider;

    public function __construct(RRPPriceProvider $RRPPriceProvider)
    {
        $this->rrpPriceProvider = $RRPPriceProvider;
    }

    /**
     * Get RRP price with unit and currencies from custom Product Price Attribute Price List
     * Called from layout.yml via: =data["product_rrp_price"].getRRPPriceWithUnitAndCurrencies(data["entity"])'
     */
    public function getRRPPriceWithUnitAndCurrencies(Product $product) : array
    {
        return $this->rrpPriceProvider->getRRPPriceWithUnitAndCurrencies($product);
    }

    /**
     * Get RRP price from custom Product Price Attribute Price List
     * Called from layout.yml via: =data["product_rrp_price"].getRRPPrice(data["entity"])'
     */
    public function getRRPPrice(Product $product) : ?string
    {
        return $this->rrpPriceProvider->getRRPPrice($product)?->getValue();
    }
}

services.yml:

services:
    # Providers
    Aligent\BaseBundle\Provider\RRPPriceProvider:
        arguments:
            - '@oro_api.doctrine_helper'
            - '@oro_pricing.providers.price_attribute_prices'

    # Layout Providers
    Aligent\BaseBundle\Layout\DataProvider\RRPPriceLayoutProvider:
        arguments:
            - '@Aligent\BaseBundle\Provider\RRPPriceProvider'
        tags:
            - { name: layout.data_provider, alias: product_rrp_price }

And then actually call it from your layout.yml:

layout:
  actions:
    - '@add':
        id: product_rrp_price
        parentId: product_price_container
        blockType: container
        options:
            vars:
                rrp_price_data: '=data["product_rrp_price"].getRRPPrice(data["product"])'

Additional Considerations

Your own use case may require customization (such as multiple attributes), and potentially a caching layer for performance reasons (such as storing the list of Price Attribute Price Lists in Redis etc instead of fetching them each time). If you plan on displaying this information on the PLP/Search pages I'd strongly recommend also including the price attributes in your search index rather than querying them for each of the 25 products per page.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chrisaligent