<?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);
}
}