Page tree
Skip to end of metadata
Go to start of metadata

ntroduction

 

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' => 'absolute''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') {

Step 3

 

Edit app/code/core/Mage/Catalog/Model/Product/Type/Price.php.

Replace all occurrences of:

  1. $finalPrice += $this->_getPricingOptionValue(array(

With:

  1. $finalPrice = ($option->getValueById($optionValue)->getPriceType() != 'absolute' ? $finalPrice : 0) + $this->_getPricingOptionValue(array(

Notes

 

Hi

I’ve tried to modify the code for version 1.6.0.0. At Step 1 you have to change the value for “absolute” because, the DB-Field (Table:catalog_product_option_type_price, Field:price_type) is of the type varchar(7) (absolute → 8, i used “abs”).

Step 2 is ok

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  = new Zend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$minPriceExpr   = $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue, $minPriceRound);
$minPriceMin    = new Zend_Db_Expr("MIN({$minPriceExpr})");
$minPrice       = $write->getCheckSql("MIN(o.is_require) = 1", $minPriceMin, '0');
 
$tierPriceRound = new Zend_Db_Expr("ROUND(i.base_tier * ({$optPriceValue} / 100), 4)");
$tierPriceExpr  = $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue, $tierPriceRound);
$tierPriceMin   = new Zend_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  = new Zend_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  = new Zend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$minPriceExpr   = $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue, $minPriceRound);
$minPriceAbs     = new Zend_Db_Expr("({$optPriceValue} - i.price)");
$minPriceAbsExpr = $write->getCheckSql("{$optPriceType} = 'abs'", $minPriceAbs, $minPriceExpr);
$minPriceExpr    = $minPriceAbsExpr;
$minPriceMin    = new Zend_Db_Expr("MIN({$minPriceExpr})");
$minPrice       = $write->getCheckSql("MIN(o.is_require) = 1", $minPriceMin, '0');
 
$tierPriceRound = new Zend_Db_Expr("ROUND(i.base_tier * ({$optPriceValue} / 100), 4)");
$tierPriceExpr  = $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue, $tierPriceRound);
$tierPriceMin   = new Zend_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  = new Zend_Db_Expr("ROUND(i.price * ({$optPriceValue} / 100), 4)");
$maxPriceExpr   = $write->getCheckSql("{$optPriceType} = 'fixed'", $optPriceValue, $maxPriceRound);
$maxPriceAbs    = new Zend_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)"); 

 

 

  • No labels