捆绑商品的价格定义在
app\code\core\Mage\Bundle\Model\Product\Price.php
通常我们使用函数 getTotalPrices() 来获取捆绑产品的价格
// 获取最大价格
$bundle_p = Mage::getModel('bundle/product_price')->getTotalPrices($product,'max',0);
// 获取最小价格
$bundle_p = Mage::getModel('bundle/product_price')->getTotalPrices($product,'min',0);
有的时候捆绑产品子产品会售罄,这时候捆绑产品的最大价格就是 除去售罄子产品后的子产品价格之和。
新的需求:
即使子产品售罄,但是捆绑产品最大价格也显示所有的总价格:
函数实现:
// 重写 core 文件 app\code\core\Mage\Bundle\Model\Product\Price.php
public function getAllSelectionsDisplayPrice($product, $which = null, $includeTax = null, $takeTierPrice = true)
{
$finalPrice = $product->getFinalPrice();
if ($product->getPriceType() == self::PRICE_TYPE_FIXED) {
$minimalPrice = $maximalPrice = Mage::helper('tax')->getPrice($product, $finalPrice, $includeTax);
} else { // PRICE_TYPE_DYNAMIC
$minimalPrice = $maximalPrice = 0;
}
$product->getTypeInstance(true)
->setStoreFilter($product->getStoreId(), $product);
$optionCollection = $product->getTypeInstance(true)
->getOptionsCollection($product);
$selectionCollection = $product->getTypeInstance(true)
->getSelectionsCollection(
$product->getTypeInstance(true)->getOptionsIds($product),
$product
);
$options = $optionCollection->appendSelections($selectionCollection, false, true);
$minPriceFounded = false;
if ($options) {
foreach ($options as $option) {
/* @var $option Mage_Bundle_Model_Option */
$selections = $option->getSelections();
if ($selections) {
$selectionMinimalPrices = array();
$selectionMaximalPrices = array();
foreach ($option->getSelections() as $selection) {
$qty = $selection->getSelectionQty();
$item = $product->getPriceType() == self::PRICE_TYPE_FIXED ? $product : $selection;
$selectionMinimalPrices[] = Mage::helper('tax')->getPrice(
$item,
$this->getSelectionFinalTotalPrice($product, $selection, 1, $qty, true, $takeTierPrice),
$includeTax
);
$selectionMaximalPrices[] = Mage::helper('tax')->getPrice(
$item,
$this->getSelectionFinalTotalPrice($product, $selection, 1, null, true, $takeTierPrice),
$includeTax
);
}
if (count($selectionMinimalPrices)) {
$selMinPrice = min($selectionMinimalPrices);
if ($option->getRequired()) {
$minimalPrice += $selMinPrice;
$minPriceFounded = true;
} elseif (true !== $minPriceFounded) {
$selMinPrice += $minimalPrice;
$minPriceFounded = (false === $minPriceFounded)
? $selMinPrice
: min($minPriceFounded, $selMinPrice);
}
if ($option->isMultiSelection()) {
$maximalPrice += array_sum($selectionMaximalPrices);
} else {
$maximalPrice += max($selectionMaximalPrices);
}
}
}
}
}
// condition is TRUE when all product options are NOT required
if (!is_bool($minPriceFounded)) {
$minimalPrice = $minPriceFounded;
}
$customOptions = $product->getOptions();
if ($product->getPriceType() == self::PRICE_TYPE_FIXED && $customOptions) {
foreach ($customOptions as $customOption) {
/* @var $customOption Mage_Catalog_Model_Product_Option */
$values = $customOption->getValues();
if ($values) {
$prices = array();
foreach ($values as $value) {
/* @var $value Mage_Catalog_Model_Product_Option_Value */
$valuePrice = $value->getPrice(true);
$prices[] = $valuePrice;
}
if (count($prices)) {
if ($customOption->getIsRequire()) {
$minimalPrice += Mage::helper('tax')->getPrice($product, min($prices), $includeTax);
}
$multiTypes = array(
//Mage_Catalog_Model_Product_Option::OPTION_TYPE_DROP_DOWN,
Mage_Catalog_Model_Product_Option::OPTION_TYPE_CHECKBOX,
Mage_Catalog_Model_Product_Option::OPTION_TYPE_MULTIPLE
);
if (in_array($customOption->getType(), $multiTypes)) {
$maximalValue = array_sum($prices);
} else {
$maximalValue = max($prices);
}
$maximalPrice += Mage::helper('tax')->getPrice($product, $maximalValue, $includeTax);
}
} else {
$valuePrice = $customOption->getPrice(true);
if ($customOption->getIsRequire()) {
$minimalPrice += Mage::helper('tax')->getPrice($product, $valuePrice, $includeTax);
}
$maximalPrice += Mage::helper('tax')->getPrice($product, $valuePrice, $includeTax);
}
}
}
$this->_isPricesCalculatedByIndex = false;
if ($which == 'max') {
return $maximalPrice;
} elseif ($which == 'min') {
return $minimalPrice;
}
return array($minimalPrice, $maximalPrice);
}
此函数是参考 getTotalPrices 实现的,其中有代码:
$options = $this->getOptions($product);
这里会过滤掉售罄产品,而我们不想他被过滤。
public function getOptions($product)
{
$product->getTypeInstance(true)
->setStoreFilter($product->getStoreId(), $product);
$optionCollection = $product->getTypeInstance(true)
->getOptionsCollection($product);
$selectionCollection = $product->getTypeInstance(true)
->getSelectionsCollection(
$product->getTypeInstance(true)->getOptionsIds($product),
$product
);
return $optionCollection->appendSelections($selectionCollection, false, false);
}
其中 appendSelections() 函数参数可以配置哪些子产品被添加:
public function appendSelections($selectionsCollection, $stripBefore = false, $appendAll = true)
{
if ($stripBefore) {
$this->_stripSelections();
}
if (!$this->_selectionsAppended) {
foreach ($selectionsCollection->getItems() as $key => $_selection) {
if ($_option = $this->getItemById($_selection->getOptionId())) {
if ($appendAll || ($_selection->isSalable() && !$_selection->getRequiredOptions())) {
$_selection->setOption($_option);
$_option->addSelection($_selection);
} else {
$selectionsCollection->removeItemByKey($key);
}
}
}
$this->_selectionsAppended = true;
}
return $this->getItems();
}
可以看到最简单的 设置参数 $appendAll 为 true 即可。
所以修改方式就是,修改了 options 的获取方式。
$options = $optionCollection->appendSelections($selectionCollection, false, true);
后面的限制:
if (!$selection->isSalable()) {
/**
* @todo CatalogInventory Show out of stock Products
*/
continue;
}
删除即可。