"
More
  • Advanced

How to Use Absolute Pricing for Custom Options

Introduction

When giving a custom option a price, Magento adds that price to the product’s base-price. This entry will show you how to add an extra price type, that allows custom options to override the base price. So instead of having “+ 10 percent” or “+£10 fixed”, you would be able to have “£25 absolute”.

Step 1

Edit app/code/core/Mage/Adminhtml/Model/System/Config/Source/Product/Options/Price.php
Replace:

  1. array(‘value’ => ‘percent’‘label’ => Mage::helper(‘adminhtml’)->__(‘Percent’))

With:

  1. array(‘value’ => ‘percent’‘label’ => Mage::helper(‘adminhtml’)->__(‘Percent’)),
  2. array(‘value’ => ‘abs’‘label’ => Mage::helper(‘adminhtml’)->__(‘Absolute’))

Step 2

Edit app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Options.php
Replace:

  1. } elseif ($type == ‘fixed’) {

With:

  1. } elseif ($type == ‘fixed’ || $type == ‘absolute’ || $type == ‘abs’) {

Step 3

Edit: app/code/core/Mage/Catalog/Model/Product/Type/Price.php
Replace (Line ~274, function _applyOptionsPrice):

  1. $finalPrice += $group->getOptionPrice($confItemOption->getValue()$basePrice);

With:

$optionPriceResult = $group->getOptionPrice($confItemOption->getValue(), $basePrice);
if (is_array($optionPriceResult)) {
    $finalPrice = $optionPriceResult[1];
}
else {
    $finalPrice += $group->getOptionPrice($confItemOption->getValue(), $basePrice);

Step 4

Edit: app/code/core/Mage/Catalog/Model/Product/Option/Type/Default.php
Replace (Line ~331):

  1. public function getOptionPrice() {
  2.     …
  3. }

With

public function getOptionPrice($optionValue, $basePrice) {
    $option = $this->getOption();
    if ($option->getPriceType() == 'abs') {
        return array('absolute', $option->getPrice());
    }
    else {
        return $this->_getChargableOptionPrice(
            $option->getPrice(),
                    $option->getPriceType() == 'percent',
                    $basePrice
            );
    }
}

Step 5

Edit: app/code/core/Mage/Catalog/Model/Product/Option/Type/Select.php
Replace (Line ~236, function getOptionPrice):

...
elseif($this->_isSingleSelection()) {
    if($_result= $option->getValueById($optionValue)) {
        $result= $this->_getChargableOptionPrice(
                $_result->getPrice(),
                    $_result->getPriceType() == 'percent',
                    $basePrice
        );
    }
    ... 
with
elseif($this->_isSingleSelection()) {
    if($_result= $option->getValueById($optionValue)) {
        if($_result->getPriceType() == 'abs') {
            $result= array('absolute', $_result->getPrice());
        }
        else{
                $result= $this->_getChargableOptionPrice(
                        $_result->getPrice(),
                        $_result->getPriceType() == 'percent',
                        $basePrice
            );
    }
    ... 
As you can see, this code works only with single selection options.

Step 6

 (min/max price calculation (e.g. for layered-nav price filter))
Edit: app/code/core/Mage/Catalog/Model/Resource/Product/Indexer/Price/Default.php
Replace (Line ~389):

$optPriceType= $write->getCheckSql('otps.option_type_price_id > 0', 'otps.price_type','otpd.price_type');
$optPriceValue= $write->getCheckSql('otps.option_type_price_id > 0', 'otps.price','otpd.price');
$minPriceRound= newZend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$minPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$minPriceRound);
$minPriceMin= newZend_Db_Expr("MIN({$minPriceExpr})");
$minPrice= $write->getCheckSql("MIN(o.is_require) = 1", $minPriceMin, '0');
 
$tierPriceRound= newZend_Db_Expr("ROUND(i.base_tier * ({$optPriceValue} / 100), 4)");
$tierPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$tierPriceRound);
$tierPriceMin= newZend_Db_Expr("MIN($tierPriceExpr)");
$tierPriceValue= $write->getCheckSql("MIN(o.is_require) > 0", $tierPriceMin, 0);
$tierPrice= $write->getCheckSql("MIN(i.base_tier) IS NOT NULL", $tierPriceValue, "NULL");
 
$maxPriceRound= newZend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$maxPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$maxPriceRound);
//$tierPriceMin   = new Zend_Db_Expr("MIN($tierPriceExpr)");
$maxPrice= $write->getCheckSql("(MIN(o.type)='radio' OR MIN(o.type)='drop_down')","MAX($maxPriceExpr)", "SUM($maxPriceExpr)"); 
with
$minPriceRound= newZend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$minPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$minPriceRound);
$minPriceAbs= newZend_Db_Expr("({$optPriceValue} - i.price)");
$minPriceAbsExpr= $write->getCheckSql("{$optPriceType} = 'abs'", $minPriceAbs,$minPriceExpr);
$minPriceExpr= $minPriceAbsExpr;
$minPriceMin= newZend_Db_Expr("MIN({$minPriceExpr})");
$minPrice= $write->getCheckSql("MIN(o.is_require) = 1", $minPriceMin, '0');
 
$tierPriceRound= newZend_Db_Expr("ROUND(i.base_tier * ({$optPriceValue} / 100), 4)");
$tierPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$tierPriceRound);
$tierPriceMin= newZend_Db_Expr("MIN($tierPriceExpr)");
$tierPriceValue= $write->getCheckSql("MIN(o.is_require) > 0", $tierPriceMin, 0);
$tierPrice= $write->getCheckSql("MIN(i.base_tier) IS NOT NULL", $tierPriceValue, "NULL");
 
$maxPriceRound= newZend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$maxPriceExpr= $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue,$maxPriceRound);
$maxPriceAbs= newZend_Db_Expr("({$optPriceValue} - i.price)");
$maxPriceAbsExpr= $write->getCheckSql("{$optPriceType} = 'abs'", $maxPriceAbs,$maxPriceExpr);
$maxPriceExpr= $maxPriceAbsExpr;
$maxPrice= $write->getCheckSql("(MIN(o.type)='radio' OR MIN(o.type)='drop_down')","MAX($maxPriceExpr)", "SUM($maxPriceExpr)"); 

Recent Articles

spot_img

Related Stories

Stay on op - Ge the daily news in your inbox