Magento – How to add a custom price attribute for RRP

magento2price

In Magento 2 CE, I'm trying to add a product attribute called "RRP" (Recommended Retail Price) and display it on the frontend product page near the other prices. (Existing MSRP function isn't appropriate because we don't use MAP.)

I'd like to use the proper price rendering functionality rather than fudging it by sticking a hard-coded currency sign in front of a raw but rounded decimal value from the attribute.

I'm following the pricing library docs but they're not very detailed.

My module, called "RRP", includes a new attribute, set up below in app/code/Acme/RRP/Setup/InstallData.php:

<?php
namespace Acme\RRP\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    protected $eavSetup;
    public function __construct(EavSetup $eavSetup)
    {
        $this->eavSetup = $eavSetup;
    }
    public function install(ModuleDataSetupInterface $setup,ModuleContextInterface $context)
    {
        $setup->startSetup();
        $this->eavSetup->addAttribute("catalog_product", "rrp", [
            'type'          => 'decimal',
            'backend'       => 'Magento\Catalog\Model\Product\Attribute\Backend\Price',
            'label'         => 'RRP',
            'input'         => 'price',
            'required'      => false,
            'global'        => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_WEBSITE,
            'group'         => 'General'
        ]);
        $setup->endSetup();
    }
}

I've tried to set up a custom price type by creating a new class that extends Magento\Framework\Pricing\Price\AbstractPrice. It lives at app/code/Acme/RRP/Pricing/Price/RRPPrice.php:

<?php

namespace Acme\RRP\Pricing\Price;

use Magento\Framework\Pricing\Price\AbstractPrice;
use Magento\Framework\Pricing\Price\BasePriceProviderInterface;

/**
 * Class RRPPrice
 */
class RRPPrice extends AbstractPrice
{
    /**
     * Price type
     */
    const PRICE_CODE = 'rrp_price';

    /**
     * Get price value
     *
     * @return float|bool
     */
    public function getValue()
    {
        if ($this->value === null) {
            $price = $this->product->getRrp();
            $priceInCurrentCurrency = $this->priceCurrency->convertAndRound($price);
            $this->value = $priceInCurrentCurrency ? floatval($priceInCurrentCurrency) : false;
        }
        return $this->value;
    }
}

And I think I need to configure the DI at app/code/Acme/RRP/etc/di.xml, although I'm not sure if I've done this correctly (since I've re-declared those included in the di.xml for the core Magento_Catalog):

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Acme\RRP\Pricing\Price\Pool" type="Magento\Framework\Pricing\Price\Pool">
        <arguments>
            <argument name="prices" xsi:type="array">
                <item name="rrp_price" xsi:type="string">Acme\RRP\Pricing\Price\RRPPrice</item>
            </argument>
            <argument name="target" xsi:type="object">Magento\Catalog\Pricing\Price\Pool</argument>
        </arguments>
    </virtualType>
    <virtualType name="Acme\RRP\Pricing\Price\Collection" type="Magento\Framework\Pricing\Price\Collection">
        <arguments>
            <argument name="pool" xsi:type="object">Acme\RRP\Pricing\Price\Pool</argument>
        </arguments>
    </virtualType>
</config>

I've declared the template for the rrp_price price type in app/code/Acme/RRP/view/base/layout/catalog_product_prices.xml (again, not sure if this is correct):

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <block class="Magento\Framework\Pricing\Render\RendererPool" name="render.product.prices">
        <arguments>
            <argument name="default" xsi:type="array">
                <item name="default_render_class" xsi:type="string">Magento\Catalog\Pricing\Render\PriceBox</item>
                <item name="default_render_template" xsi:type="string">Magento_Catalog::product/price/default.phtml</item>
                <item name="default_amount_render_class" xsi:type="string">Magento\Framework\Pricing\Render\Amount</item>
                <item name="default_amount_render_template" xsi:type="string">Magento_Catalog::product/price/amount/default.phtml</item>
                <item name="prices" xsi:type="array">
                    <item name="special_price" xsi:type="array">
                        <item name="render_template" xsi:type="string">Magento_Catalog::product/price/special_price.phtml</item>
                    </item>
                    <item name="tier_price" xsi:type="array">
                        <item name="render_template" xsi:type="string">Magento_Catalog::product/price/tier_prices.phtml</item>
                    </item>
                    <item name="final_price" xsi:type="array">
                        <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\FinalPriceBox</item>
                        <item name="render_template" xsi:type="string">Magento_Catalog::product/price/final_price.phtml</item>
                    </item>
                    <item name="custom_option_price" xsi:type="array">
                        <item name="amount_render_template" xsi:type="string">Magento_Catalog::product/price/amount/default.phtml</item>
                    </item>
                    <item name="configured_price" xsi:type="array">
                        <item name="render_class" xsi:type="string">Magento\Catalog\Pricing\Render\ConfiguredPriceBox</item>
                        <item name="render_template" xsi:type="string">Magento_Catalog::product/price/configured_price.phtml</item>
                    </item>
                    <item name="rrp_price" xsi:type="array">
                        <item name="render_template" xsi:type="string">Acme_RRP::product/price/rrp_price.phtml</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </block>
</layout>

I created a template for the RRP price at app/code/Acme/RRP/view/base/templates/product/price/rrp_price.phtml:

<?php
/** @var \Magento\Catalog\Pricing\Render\FinalPriceBox $block */

$productId = $block->getSaleableItem()->getId();

/** @var \Magento\Catalog\Pricing\Price\RegularPrice $priceModel */
$priceModel = $block->getPriceType('regular_price');

/* @escapeNotVerified */ echo $block->renderAmount($priceModel->getAmount(), [
    'price_id'          => $block->getPriceId('product-price-'),
    'include_container' => true
]);
?>

Finally, I override the final_price.phtml template to include a call to render the new RRP price. This lives at app/design/frontend/Acme/[mytheme]/Magento_Catalog/templates/product/price/final_price.phtml:

<?php
/** @var \Magento\Catalog\Pricing\Render\FinalPriceBox $block */

$productId = $block->getSaleableItem()->getId();

/** @var \Magento\Catalog\Pricing\Price\RegularPrice $priceModel */
$priceModel = $block->getPriceType('regular_price');

/** @var \Magento\Catalog\Pricing\Price\FinalPrice $finalPriceModel */
$finalPriceModel = $block->getPriceType('final_price');

/** @var \Acme\RRP\Pricing\Price\RRPPrice $rrpPriceModel */
$rrpPriceModel = $block->getPriceType('rrp_price');

$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : '';
$schema = ($block->getZone() == 'item_view') ? true : false;
?>

<?php /* @escapeNotVerified */ echo $block->renderAmount($rrpPriceModel->getAmount(), [
    'price_id'          => $block->getPriceId('rrp-price-' . $idSuffix),
    'price_type'        => 'rrpPrice',
    'include_container' => true,
    'schema'            => $schema
]); ?>

<?php if ($block->hasSpecialPrice()): ?>
    <span class="special-price">
        <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
            'display_label'     => __('Special Price'),
            'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
            'price_type'        => 'finalPrice',
            'include_container' => true,
            'schema' => $schema
        ]); ?>
    </span>
    <span class="old-price">
        <?php /* @escapeNotVerified */ echo $block->renderAmount($priceModel->getAmount(), [
            'display_label'     => __('Regular Price'),
            'price_id'          => $block->getPriceId('old-price-' . $idSuffix),
            'price_type'        => 'oldPrice',
            'include_container' => true,
            'skip_adjustments'  => true
        ]); ?>
    </span>
<?php else: ?>
    <?php /* @escapeNotVerified */ echo $block->renderAmount($finalPriceModel->getAmount(), [
        'price_id'          => $block->getPriceId('product-price-' . $idSuffix),
        'price_type'        => 'finalPrice',
        'include_container' => true,
        'schema' => $schema
    ]); ?>
<?php endif; ?>

<?php if ($block->showMinimalPrice()): ?>
    <?php if ($block->getUseLinkForAsLowAs()):?>
        <a href="<?php /* @escapeNotVerified */ echo $block->getSaleableItem()->getProductUrl(); ?>" class="minimal-price-link">
            <?php /* @escapeNotVerified */ echo $block->renderAmountMinimal(); ?>
        </a>
    <?php else:?>
        <span class="minimal-price-link">
            <?php /* @escapeNotVerified */ echo $block->renderAmountMinimal(); ?>
        </span>
    <?php endif?>
<?php endif; ?>

When I re-run the compile, clear caches and so on, and then refresh the product page, I get the following:

Class  does not exist
#0 /[mypath]/vendor/magento/framework/Code/Reader/ClassReader.php(19): ReflectionClass->__construct('')
#1 /[mypath]/vendor/magento/framework/ObjectManager/Definition/Runtime.php(44): Magento\Framework\Code\Reader\ClassReader->getConstructor('')
#2 /[mypath]/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php(71): Magento\Framework\ObjectManager\Definition\Runtime->getParameters('')
#3 /[mypath]/vendor/magento/framework/ObjectManager/ObjectManager.php(57): Magento\Framework\ObjectManager\Factory\Dynamic\Developer->create('', Array)
#4 /[mypath]/vendor/magento/framework/Pricing/Price/Factory.php(47): Magento\Framework\ObjectManager\ObjectManager->create(NULL, Array)
#5 /[mypath]/vendor/magento/framework/Pricing/Price/Collection.php(137): Magento\Framework\Pricing\Price\Factory->create(Object(Magento\Catalog\Model\Product\Interceptor), NULL, NULL)
#6 /[mypath]/vendor/magento/framework/Pricing/PriceInfo/Base.php(61): Magento\Framework\Pricing\Price\Collection->get('rrp_price')
#7 /[mypath]/vendor/magento/framework/Pricing/Render/PriceBox.php(111): Magento\Framework\Pricing\PriceInfo\Base->getPrice('rrp_price')
#8 /[mypath]/app/design/frontend/Acme/[themename]/Magento_Catalog/templates/product/price/final_price.phtml(23): Magento\Framework\Pricing\Render\PriceBox->getPriceType('rrp_price')
#9 /[mypath]/vendor/magento/framework/View/TemplateEngine/Php.php(59): include('/Users/[username]...')
#10 /[mypath]/vendor/magento/module-developer/Model/TemplateEngine/Decorator/DebugHints.php(42): Magento\Framework\View\TemplateEngine\Php->render(Object(Magento\Catalog\Pricing\Render\FinalPriceBox), '/Users/[username]...', Array)
#11 /[mypath]/vendor/magento/framework/View/Element/Template.php(255): Magento\Developer\Model\TemplateEngine\Decorator\DebugHints->render(Object(Magento\Catalog\Pricing\Render\FinalPriceBox), '/Users/[username]...', Array)
#12 /[mypath]/vendor/magento/framework/View/Element/Template.php(279): Magento\Framework\View\Element\Template->fetchView('/Users/[username]...')
#13 /[mypath]/vendor/magento/framework/Pricing/Render/PriceBox.php(65): Magento\Framework\View\Element\Template->_toHtml()
#14 /[mypath]/vendor/magento/module-catalog/Pricing/Render/FinalPriceBox.php(31): Magento\Framework\Pricing\Render\PriceBox->_toHtml()
#15 /[mypath]/vendor/magento/framework/View/Element/AbstractBlock.php(657): Magento\Catalog\Pricing\Render\FinalPriceBox->_toHtml()
#16 /[mypath]/vendor/magento/framework/Pricing/Render.php(99): Magento\Framework\View\Element\AbstractBlock->toHtml()
#17 /[mypath]/vendor/magento/module-catalog/Pricing/Render.php(58): Magento\Framework\Pricing\Render->render('final_price', Object(Magento\Catalog\Model\Product\Interceptor), Array)
#18 /[mypath]/vendor/magento/framework/View/Element/AbstractBlock.php(657): Magento\Catalog\Pricing\Render->_toHtml()
#19 /[mypath]/vendor/magento/framework/View/Layout.php(542): Magento\Framework\View\Element\AbstractBlock->toHtml()
#20 /[mypath]/vendor/magento/framework/View/Layout.php(518): Magento\Framework\View\Layout->_renderBlock('product.price.f...')
#21 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('product.price.f...')
#22 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#23 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#24 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('product.price.f...')
#25 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('product.price.f...', true)
#26 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('product.price.f...')
#27 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('product.info.pr...')
#28 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('product.info.pr...')
#29 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#30 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#31 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('product.info.pr...')
#32 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('product.info.pr...', true)
#33 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('product.info.pr...')
#34 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('product.info.bu...')
#35 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('product.info.bu...')
#36 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#37 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#38 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('product.info.bu...')
#39 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('product.info.bu...', true)
#40 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('product.info.bu...')
#41 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('product.info.ma...')
#42 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('product.info.ma...')
#43 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#44 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#45 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('product.info.ma...')
#46 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('product.info.ma...', true)
#47 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('product.info.ma...')
#48 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('content')
#49 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('content')
#50 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#51 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#52 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('content')
#53 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('content', true)
#54 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('content')
#55 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('main')
#56 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('main')
#57 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#58 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#59 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('main')
#60 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('main', true)
#61 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('main')
#62 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('columns')
#63 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('columns')
#64 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#65 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#66 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('columns')
#67 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('columns', true)
#68 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('columns')
#69 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('main.content')
#70 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('main.content')
#71 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#72 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#73 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('main.content')
#74 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('main.content', true)
#75 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('main.content')
#76 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('page.wrapper')
#77 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('page.wrapper')
#78 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#79 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#80 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('page.wrapper')
#81 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('page.wrapper', true)
#82 /[mypath]/vendor/magento/framework/View/Layout.php(569): Magento\Framework\View\Layout\Interceptor->renderElement('page.wrapper')
#83 /[mypath]/vendor/magento/framework/View/Layout.php(520): Magento\Framework\View\Layout->_renderContainer('root')
#84 [internal function]: Magento\Framework\View\Layout->renderNonCachedElement('root')
#85 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#86 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(208): Magento\Framework\View\Layout\Interceptor->___callPlugins('renderNonCached...', Array, Array)
#87 /[mypath]/vendor/magento/framework/View/Layout.php(472): Magento\Framework\View\Layout\Interceptor->renderNonCachedElement('root')
#88 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(193): Magento\Framework\View\Layout->renderElement('root', true)
#89 /[mypath]/vendor/magento/framework/View/Layout.php(938): Magento\Framework\View\Layout\Interceptor->renderElement('root')
#90 [internal function]: Magento\Framework\View\Layout->getOutput()
#91 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(144): call_user_func_array(Array, Array)
#92 /[mypath]/var/generation/Magento/Framework/View/Layout/Interceptor.php(494): Magento\Framework\View\Layout\Interceptor->___callPlugins('getOutput', Array, Array)
#93 /[mypath]/vendor/magento/framework/View/Result/Page.php(241): Magento\Framework\View\Layout\Interceptor->getOutput()
#94 /[mypath]/vendor/magento/framework/View/Result/Layout.php(162): Magento\Framework\View\Result\Page->render(Object(Magento\Framework\App\Response\Http\Interceptor))
#95 [internal function]: Magento\Framework\View\Result\Layout->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#96 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(74): call_user_func_array(Array, Array)
#97 /[mypath]/vendor/magento/framework/Interception/Chain/Chain.php(70): Magento\Framework\View\Result\Page\Interceptor->___callParent('renderResult', Array)
#98 /[mypath]/vendor/magento/framework/Interception/Chain/Chain.php(63): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-varnish-...')
#99 /[mypath]/vendor/magento/module-page-cache/Model/Controller/Result/VarnishPlugin.php(74): Magento\Framework\Interception\Chain\Chain->Magento\Framework\Interception\Chain\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#100 [internal function]: Magento\PageCache\Model\Controller\Result\VarnishPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#101 /[mypath]/vendor/magento/framework/Interception/Chain/Chain.php(68): call_user_func_array(Array, Array)
#102 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(136): Magento\Framework\Interception\Chain\Chain->invokeNext('Magento\\Framewo...', 'renderResult', Object(Magento\Framework\View\Result\Page\Interceptor), Array, 'result-builtin-...')
#103 /[mypath]/vendor/magento/module-page-cache/Model/Controller/Result/BuiltinPlugin.php(67): Magento\Framework\View\Result\Page\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Response\Http\Interceptor))
#104 [internal function]: Magento\PageCache\Model\Controller\Result\BuiltinPlugin->aroundRenderResult(Object(Magento\Framework\View\Result\Page\Interceptor), Object(Closure), Object(Magento\Framework\App\Response\Http\Interceptor))
#105 /[mypath]/vendor/magento/framework/Interception/Interceptor.php(141): call_user_func_array(Array, Array)
#106 /[mypath]/var/generation/Magento/Framework/View/Result/Page/Interceptor.php(130): Magento\Framework\View\Result\Page\Interceptor->___callPlugins('renderResult', Array, Array)
#107 /[mypath]/vendor/magento/framework/App/Http.php(119): Magento\Framework\View\Result\Page\Interceptor->renderResult(Object(Magento\Framework\App\Response\Http\Interceptor))
#108 /[mypath]/vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http->launch()
#109 /[mypath]/pub/index.php(37): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http))
#110 {main}

Clearly, the configuration is wrong in one or more places?

Best Answer

There are some minor problems in your XML Files.

app/code/Acme/RRP/view/base/layout/catalog_product_prices.xml

You are overriding the render.product.prices block. Instead you have to reference the block:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <referenceBlock name="render.product.prices">
        <arguments>
            <argument name="default" xsi:type="array">
                <item name="prices" xsi:type="array">
                    <item name="rrp_price" xsi:type="array">
                        <item name="render_template" xsi:type="string">Acme_RRP::product/price/rrp_price.phtml</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</layout>


app/code/Acme/RRP/etc/di.xml

The virtualType of the collection isn't needed. You just need to update the price type pool with your new type:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Pricing\Price\Pool">
        <arguments>
            <argument name="prices" xsi:type="array">
                <item name="rrp_price" xsi:type="string">Acme\RRP\Pricing\Price\RRPPrice</item>
            </argument>
        </arguments>
    </virtualType>
</config>
Related Topic