0

We have come across an issue that I'm trying to solve. In order to overcome this bug https://github.com/magento/magento2/issues/10009 where discounted prices are not applied per customer group, I've created a module that will handle this. I have set up a database table which looks like this: enter image description here

And I need to render the price on the product list and product view page. I want to use the built in price renderer but I am unable to figure out how to do this. Currently my code looks like this:

public function getCustomerGroupSpecialPrice($productId)
{

    $collection = $this->customerGroupPricesCollectionFactory->create();
    $collection->getSelect();
    $collection->addFieldToFilter('product_id', array('eq' => $productId))
                       ->addFieldToFilter('customer_group_id', array('eq' => $this->getCustomerGroupId()));
    foreach ($collection as $item) {
        $price = $item->getData('price');
    }
    return $price;
}

This does get the correct price but it looks like this: enter image description here

and what I need is for the price to be rendered like this:

enter image description here

I've tried overriding the price like this:

class CustomerGroupSpecialPrice extends AbstractPrice
{
    /**
     * Price type identifier string
     */
    const PRICE_CODE = 'customer_group_special_price';

    protected $customerGroupPricesCollectionFactory;

    public function __construct(
        \Icansee\CustomerGroupsPrices\Model\ResourceModel\CustomerGroup\CollectionFactory $customerGroupPricesCollectionFactory
    ) {
        $this->customerGroupPricesCollectionFactory = $customerGroupPricesCollectionFactory;
    }
    /**
     * Get Base Price Value
     *
     * @return float|bool
     */
    public function getValue()
    {
        if ($this->value === null) {
            $this->value = false;
            $collection = $this->customerGroupPricesCollectionFactory->create();
            $collection->getSelect();
            $collection->addFieldToFilter('product_id', array('eq' => $productId))
                               ->addFieldToFilter('customer_group_id', array('eq' => $this->getCustomerGroupId()));
            foreach ($collection as $item) {
                $price = $item->getData('price');
            }
            $this->value = $price;
        }
        return $this->value;
    }
}

but I get an error of class not found as the PRICE_CODE 'customer_group_special_price' does not exist within Magento and so I can't do it this way. I don't really want to code in the HTML into the template to render the price correctly, as we need to render this price in multiple places, such as a quickview modal popup, product view etc. so I would need to hard code this in multiple places and that won't do. How can I render the price value correctly from my custom table?

  • Are you need to format your price ? – Vignesh Bala Dec 13 '18 at 12:46
  • Yes. I need to get this price into the price box so that I can just render it where needed and it is consistent with the default price renderer. – David Dec 13 '18 at 12:47
  • How to set discount for your product price ? Is it from group pricing ? – Vignesh Bala Dec 13 '18 at 12:48
  • It is a discount percent. I have a script that imports the discount percentage into Magento and calculates the discounted price per customer group for each product. This value is then inserted into the above table (works like the magento 1 module Webtex customergroups prices, which is unavailable for Magento 2). However, the discount percent is only applied to the final price and not the tier prices so I'm trying to get around this. It's the subject of the issue I linked to. – David Dec 13 '18 at 12:51
  • Is Discount percent is common for all products based on customer group ? – Vignesh Bala Dec 13 '18 at 12:54
0

Use below code to format price in your phtml file.

$this->helper('Magento\Framework\Pricing\Helper\Data')->currency(number_format(50,2),true,false);

Replace 50 by your price in this.

Edit

Add a new module with a phtml to display price in what ever format you want. And you can use this in anywhere you want using layouts.

  • This formats the price but what I need is to bring in the price-block html so that it is consistent with the prices that are not discounted. I also need to use this in other places, such as a quickview popup modal, wishlist item view etc. so ideally I need to create a custom price renderer that I can call with something like $_product->getCustomerGroupSpecialPrice() in the same way as $_product->getFinalPrice() works. – David Dec 13 '18 at 13:12
0

I fixed this issue by writing a plugin to get the special price for the customer's group after getPrice is called, which then uses the discount price if there is one and the product's price if there isn't. This renders the price box html with the required price showing in all areas of Magento, from the product list to the checkout and items are ordered with the discounted price as well.

I created etc/di.xml in my module:

<config>
<type name="Magento\Catalog\Model\Product">
    <plugin name="change_product" type="Vendor\Module\Plugin\Product" sortOrder="1" disabled="true" />
</type>

then I moved my getCustomerGroupSpecialPrice function to the plugin and use it there to modify the price with the custom price retrieved from the table of prices I set up. This works perfectly for anyone who needs to set customer group special prices.

EDIT:

A side effect of this is that every call to getPrice() will be overridden by the plugin. To get around displaying incorrect prices in the order view I had to also write an observer as shown below:

<?php

namespace Vendor\Module\Observer;

use \Magento\Framework\Event\ObserverInterface; use \Magento\Framework\Event\Observer as EventObserver;

class OrderSaveAfter implements ObserverInterface { /** * @var \Psr\Log\LoggerInterface */ protected $_logger;

protected $productFactory;

protected $quoteToOrder;

protected $quoteFactory;

protected $taxHelper;

public function __construct(
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Psr\Log\LoggerInterface $logger,
    \Magento\Quote\Model\Quote\Item\ToOrderItem $quoteToOrder,
    \Magento\Quote\Model\QuoteFactory $quoteFactory,
    \Magento\Catalog\Helper\Data $taxHelper
) {
    $this->productFactory = $productFactory;
    $this->_logger = $logger;
    $this->quoteToOrder = $quoteToOrder;
    $this->quoteFactory = $quoteFactory;
    $this->taxHelper = $taxHelper;
}

/**
 * @param EventObserver $observer
 */
public function execute(\Magento\Framework\Event\Observer $observer)
{
    /** @var \Magento\Sales\Model\Order $order */
    $order = $observer->getEvent()->getOrder();

    if (!$order) {
        return;
    }

    $quote = $this->quoteFactory->create()->load($order->getQuoteId());
    $this->_logger->addInfo("QUOTE ID: " . $quote->getId());

    foreach ($quote->getAllVisibleItems() as $quoteItem) {
        $discountAmount = 0;
        $origOrderItem = $order->getItemByQuoteItemId($quoteItem->getId());
        $orderItemId = $origOrderItem->getItemId();
        $productId = $quoteItem->getProductId();
        $product = $this->productFactory->create()->load($productId);
        $originalPrice = $product->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue();
        $discountAmount = ($originalPrice / 100) * $product->getSaleDiscountPercent();
        $quoteItem->setDiscountAmount($discountAmount);
        $quoteItem->setOriginalPrice($originalPrice);
        $inclTaxPrice = $this->taxHelper->getTaxPrice($product, $originalPrice, true);
        $quoteItem->setRowTotal($inclTaxPrice);
    }
    $quote->save();

    foreach ($quote->getAllVisibleItems() as $quoteItem) {
        $orderItem = $this->quoteToOrder->convert($quoteItem);
        $origOrderItemNew = $order->getItemByQuoteItemId($quoteItem->getId());

        if ($origOrderItemNew) {
            $origOrderItemNew->addData($orderItem->getData());
        } else {
            if ($quoteItem->getParentItem()) {
                $orderItem->setParentItem(
                    $order->getItemByQuoteItemId($orderItem->getParentItem()->getId())
                );
            }
            $order->addItem($orderItem);
        }
    }
    $order->save();

    return $order;
}

}

This uses the following events.xml:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_save_after">
    <observer name="save_item_discount_amounts" instance="Icansee\CustomerGroupsPrices\Observer\OrderSaveAfter" />
</event>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.