Skip to content

In Magento 2, I used the code below, but when I enabled the FPC the custom price for the product was not updated before adding it to the cart product

<?php
/**
 * @package     Bliss_PricePerCustomer
 * @author      Bliss Web Solution Pvt. Ltd
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 * @copyright   Copyright (c) 2025 Bliss Web Solution Pvt.Ltd (https://www.blisswebsolution.com/)
 */
namespace BlissPricePerCustomerPluginModel;

use MagentoCustomerModelSession;
use BlissPricePerCustomerModelCustomerPriceProdcut;
use MagentoFrameworkAppConfigScopeConfigInterface;
use MagentoStoreModelScopeInterface;
use MagentoCatalogModelProduct as MainProduct;

class Product
{
    /**
     * @var Session
     */
    protected $customerSession;

    /**
     * @var CustomerPriceProdcut
     */
    protected $customerPriceProdcut;

    /**
     * @var ScopeConfigInterface
     */
    public $scopeConfig;

    /**
     * Configuration path for enabling the module.
     */
    const ENABLE_PRICEPER_CUSTOMER = 'bliss/settings/enable';

    /**
     * Product constructor.
     *
     * @param Session $customerSession
     * @param CustomerPriceProdcut $customerPriceProdcut
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        Session $customerSession,
        CustomerPriceProdcut $customerPriceProdcut,
        ScopeConfigInterface $scopeConfig
    ) {
        $this->customerSession = $customerSession;
        $this->customerPriceProdcut = $customerPriceProdcut;
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * Modify product price based on the customer's global price adjustment attribute or product-specific prices.
     *
     * @param MagentoCatalogModelProduct $subject
     * @param float $result
     * @return float
     */
    public function afterGetPrice($subject, $result)
    {
        $moduleEnableValue = $this->getModuleEnable();
        $customer = $this->customerSession->getCustomer();

        if ($customer->getId() && $moduleEnableValue == 1) {
            $customerId = $customer->getId();
            $productId = $subject->getId();

            // Fetch product-specific price adjustment if available
            $productPriceData = $this->getProductPriceData($customerId, $productId);

            $customerSpecificPrice = null;

            if ($productPriceData) {
                $customerSpecificPrice = $productPriceData->getCustomerPrice();
            }
            // Retrieve global customer price
            $globalCustomerPrice = $customer->getData('global_customer_price');

            // Determine the highest price between product-specific and global price
            if ($customerSpecificPrice !== null && $globalCustomerPrice !== null) {
                $finalPrice = max($customerSpecificPrice, $globalCustomerPrice);
            } elseif ($customerSpecificPrice !== null) {
                $finalPrice = $customerSpecificPrice;
            } elseif ($globalCustomerPrice !== null) {
                $finalPrice = $globalCustomerPrice;
            } else {
                // No adjustments available, return the original price
                return $result;
            }
            // Return the calculated price
            return $this->calculateAdjustedPrice($result, $finalPrice);
        }
        // Return the original price if no adjustments are applied
        return $result;
    }


    /**
     * Modify the special price based on the customer's global price adjustment or product-specific prices.
     *
     * @param MagentoCatalogModelProduct $subject
     * @param float|null $result
     * @return float|null
     */
    public function afterGetSpecialPrice($subject, $result)
    {
        if (!$result) {
            return $result;
        }

        $moduleEnableValue = $this->getModuleEnable();
        $customer = $this->customerSession->getCustomer();

        if ($customer->getId() && $moduleEnableValue == 1) {
            $customerId = $customer->getId();
            $productId = $subject->getId();

            // Fetch product-specific special price adjustment if available
            $productPriceData = $this->getProductPriceData($customerId, $productId);
            $customerSpecialPrice = null;

            if ($productPriceData) {
                $customerSpecialPrice = $productPriceData->getCustomerSpecialPrice();
            }

            // Retrieve global customer special price
            $globalCustomerSpecialPrice = $customer->getData('global_customer_special_price');

            // Determine the highest special price between product-specific and global price
            if ($customerSpecialPrice !== null && $globalCustomerSpecialPrice !== null) {
                $finalSpecialPrice = max($customerSpecialPrice, $globalCustomerSpecialPrice);
            } elseif ($customerSpecialPrice !== null) {
                $finalSpecialPrice = $customerSpecialPrice;
            } elseif ($globalCustomerSpecialPrice !== null) {
                $finalSpecialPrice = $globalCustomerSpecialPrice;
            } else {
            // No adjustments available, return the original special price
                return $result;
            }
            // Return the calculated special price
            return $this->calculateAdjustedPrice($result, $finalSpecialPrice);
        }
        // Return the original special price if no adjustments are applied
        return $result;
    }


    /**
     * Fetch product-specific pricing data for a given customer and product using the model.
     *
     * @param int $customerId
     * @param int $productId
     * @return BlissPricePerCustomerModelCustomerPriceProdcut|null
     */
    protected function getProductPriceData($customerId, $productId)
    {
        return $this->customerPriceProdcut->getCollection()
            ->addFieldToFilter('entity_id', $customerId)
            ->addFieldToFilter('product_id', $productId)
            ->getFirstItem();
    }

    /**
     * Calculate adjusted price based on the customer-specific adjustment.
     *
     * @param float $basePrice
     * @param string|float $adjustment
     * @return float
     */
    protected function calculateAdjustedPrice($basePrice, $adjustment)
    {
        if (strpos($adjustment, '%') !== false) {
            // Percentage-based adjustment
            $percentageValue = floatval(trim($adjustment, '%'));
            $adjustedPrice = $basePrice - ($basePrice * ($percentageValue / 100));
        } else {
            // Flat adjustment
            $adjustment = floatval($adjustment);
            $adjustedPrice = $basePrice + $adjustment;
        }
        return round($adjustedPrice, 2);
    }

    /**
     * Retrieve the value of the module enable configuration setting.
     *
     * @return int|null
     */
    public function getModuleEnable()
    {
        return $this->scopeConfig->getValue( self::ENABLE_PRICEPER_CUSTOMER, ScopeInterface::SCOPE_STORE);
    }
}