I am now struggling to create a new price type on Magento 2.2.7. Below are what I have tried so far.
I have created a module Foo_Bar.
And then, first of all, inject the new type into the price pool:
Foo\Bar\etc\di.xml
<virtualType name="Magento\Catalog\Pricing\Price\Pool"> <arguments> <argument name="prices" xsi:type="array"> <item name="custom_price" xsi:type="string">Foo\Bar\Pricing\Price\CustomPrice</item> </argument> </arguments> </virtualType>
Define the price class:
Foo\Bar\Pricing\Price\CustomPrice.php
namespace Foo\Bar\Pricing\Price; use Magento\Framework\Pricing\Price\AbstractPrice; class CustomPrice extends AbstractPrice { const PRICE_CODE = 'custom_price'; public function getValue() { return '1234'; // for testing purpose } }
I have deleted all files under generated/code, generated/metadata, and I have run all the commands I could think of:
php bin/magento s:d:c php bin/magento c:c php bin/magento c:f
Then, for testing purpose, I tried to edit the core block Magento\Catalog\Pricing\Render\FinalPriceBox and added some codes in the function _toHtml() as follows:
echo 'final_price: ' . $this->getPriceType('final_price')->getAmount()->getValue() . '<br/>'; echo 'regular_price: ' . $this->getPriceType('regular_price')->getAmount()->getValue() . '<br/>'; echo 'base_price: ' . $this->getPriceType('base_price')->getAmount()->getValue() . '<br/>'; echo 'tier_price: ' . $this->getPriceType('tier_price')->getAmount()->getValue() . '<br/>'; echo 'special_price: ' . $this->getPriceType('special_price')->getAmount()->getValue() . '<br/>'; // the following line is commented out because it is giving me another irrelevant error about illegal offset //echo 'custom_option_price: ' . $this->getPriceType('custom_option_price')->getAmount()->getValue() . '<br/>'; echo 'configured_price: ' . $this->getPriceType('configured_price')->getAmount()->getValue() . '<br/>'; echo 'configured_regular_price: ' . $this->getPriceType('configured_regular_price')->getAmount()->getValue() . '<br/>'; echo 'catalog_rule_price: ' . $this->getPriceType('catalog_rule_price')->getAmount()->getValue() . '<br/>'; echo 'msrp_price: ' . $this->getPriceType('msrp_price')->getAmount()->getValue() . '<br/>'; echo 'wishlist_configured_price: ' . $this->getPriceType('wishlist_configured_price')->getAmount()->getValue() . '<br/>'; // the line below would result in an exception //echo 'custom_price: ' . $this->getPriceType('custom_price')->getAmount()->getValue() . '<br/>'; die();
Basically what I was trying to do is to see if I could retrieve the price type I defined earlier. All the lines except the two I have commented out worked properly. And the last line is giving me an exception like this:
Exception #0 (ReflectionException): Class does not exist
And part of the related traces:
/vendor/magento/framework/Pricing/Price/Collection.php(138): Magento\Framework\Pricing\Price\Factory->create(Object(Magento\Catalog\Model\Product\Interceptor), NULL, NULL) /vendor/magento/framework/Pricing/PriceInfo/Base.php(63): Magento\Framework\Pricing\Price\Collection->get('custom_price') /vendor/magento/framework/Pricing/Render/PriceBox.php(135): Magento\Framework\Pricing\PriceInfo\Base->getPrice('custom_price') /vendor/magento/module-catalog/Pricing/Render/FinalPriceBox.php(97): Magento\Framework\Pricing\Render\PriceBox->getPriceType('custom_price') /vendor/magento/framework/View/Element/AbstractBlock.php(667): Magento\Catalog\Pricing\Render\FinalPriceBox->_toHtml()
And from Magento\Framework\Pricing\Price\Factory->create(Object(Magento\Catalog\Model\Product\Interceptor), NULL, NULL), we could find some hints in Magento\Framework\Pricing\Price\Collection:
Magento\Framework\Pricing\Price\Collection
public function get($code) { if (!isset($this->priceModels[$code])) { $this->priceModels[$code] = $this->priceFactory->create( $this->saleableItem, $this->pool[$code], $this->quantity ); } return $this->priceModels[$code]; }
From here we could see that $this->pool[$code] which would be $this->pool['custom_price'] in this case, is NULL. This made me think that my custom price type is still nowhere to be found inside the price pool.
What am I missing here?
I hope I am clear enough and thanks for any assistance in advance.
Hello,
I'm trying to do the same things! Did you manage to make it work ?
Anyone could help on this topic ?
Thank you
Hey,
Did you manage to achieve it the new price type ?
I had the same problem and finally solved it by implementing the new price like the magento-msrp module implements the MSRP price, creating a virtual type for bundle products too:
etc/di.xml:
<virtualType name="Magento\Catalog\Pricing\Price\Pool"> <arguments> <argument name="prices" xsi:type="array"> <item name="store_price" xsi:type="string">MyVendor\MyModule\Pricing\Price\StorePrice</item> </argument> </arguments> </virtualType> <virtualType name="Magento\Bundle\Pricing\Price\Pool"> <arguments> <argument name="prices" xsi:type="array"> <item name="store_price" xsi:type="string">MyVendor\MyModule\Pricing\Price\StorePrice</item> </argument> </arguments> </virtualType>
And my price model:
<?php namespace MyVendor\MyModule\Pricing\Price; use Magento\Catalog\Model\Product; use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Catalog\Pricing\Price\FinalPriceInterface; use Magento\Framework\Pricing\Adjustment\CalculatorInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; /** * Store price model */ class StorePrice extends FinalPrice implements FinalPriceInterface { /** * Default price type */ const PRICE_CODE = 'store_price'; /** * @param Product $saleableItem * @param float $quantity * @param CalculatorInterface $calculator * @param PriceCurrencyInterface $priceCurrency */ public function __construct( Product $saleableItem, $quantity, CalculatorInterface $calculator, PriceCurrencyInterface $priceCurrency ) { parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency); } /** * Get price value * * @return float */ public function getValue() { if ($this->value === null) { $price = $this->product->getStorePrice(); $priceInCurrentCurrency = $this->priceCurrency->convertAndRound($price); $this->value = $priceInCurrentCurrency ? (float)$priceInCurrentCurrency : 0; } return $this->value; } }
My class extends the Magento\Catalog\Pricing\Price\FinalPrice class and implements Magento\Catalog\Pricing\Price\FinalPriceInterface class.
Hope this help.
I see you created a new price type named custom_price but you try to get configured_price,configured_regular_price. Please create a new pool in di.xml for each price type in order to get these prices.