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.