00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 class Mage_Bundle_Model_Product_Price extends Mage_Catalog_Model_Product_Type_Price
00035 {
00036 const PRICE_TYPE_FIXED = 1;
00037 const PRICE_TYPE_DYNAMIC = 0;
00038
00039
00040
00041
00042
00043
00044 public function getPrice($product)
00045 {
00046 if ($product->getPriceType() == self::PRICE_TYPE_FIXED) {
00047 return $product->getData('price');
00048 } else {
00049 return 0;
00050 }
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060 public function getFinalPrice($qty=null, $product)
00061 {
00062 if (is_null($qty) && !is_null($product->getCalculatedFinalPrice())) {
00063 return $product->getCalculatedFinalPrice();
00064 }
00065
00066 $finalPrice = $product->getPrice();
00067
00068
00069
00070
00071 if ($finalPrice) {
00072 $tierPrice = $this->_applyTierPrice($product, $qty, $finalPrice);
00073 $specialPrice = $this->_applySpecialPrice($product, $finalPrice);
00074 $finalPrice = min(array($tierPrice, $specialPrice));
00075 $product->setFinalPrice($finalPrice);
00076 Mage::dispatchEvent('catalog_product_get_final_price', array('product'=>$product));
00077 $finalPrice = $product->getData('final_price');
00078 }
00079 $basePrice = $finalPrice;
00080
00081 if ($product->hasCustomOptions()) {
00082 $customOption = $product->getCustomOption('bundle_option_ids');
00083 $customOption = $product->getCustomOption('bundle_selection_ids');
00084 $selectionIds = unserialize($customOption->getValue());
00085 $selections = $product->getTypeInstance(true)->getSelectionsByIds($selectionIds, $product);
00086 foreach ($selections->getItems() as $selection) {
00087 if ($selection->isSalable()) {
00088 $selectionQty = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
00089 if ($selectionQty) {
00090 $finalPrice = $finalPrice + $this->getSelectionFinalPrice($product, $selection, $qty, $selectionQty->getValue());
00091 }
00092 }
00093 }
00094 } else {
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 }
00110
00111 $finalPrice = $finalPrice + $this->_applyOptionsPrice($product, $qty, $basePrice) - $basePrice;
00112 $product->setFinalPrice($finalPrice);
00113
00114 return max(0, $product->getData('final_price'));
00115 }
00116
00117 public function getChildFinalPrice($product, $productQty, $childProduct, $childProductQty)
00118 {
00119 return $this->getSelectionFinalPrice($product, $childProduct, $productQty, $childProductQty, false);
00120 }
00121
00122 public function getPrices($product, $which = null)
00123 {
00124
00125 if ($product->getData('_price_index')) {
00126 $minimalPrice = $product->getData('_price_index_min_price');
00127 $maximalPrice = $product->getData('_price_index_max_price');
00128 }
00129 else {
00130
00131
00132
00133 if ($product->getPriceType()) {
00134 $minimalPrice = $maximalPrice = $product->getFinalPrice();
00135 } else {
00136 $minimalPrice = $maximalPrice = $product->getPrice();
00137 }
00138
00139 if ($options = $this->getOptions($product)) {
00140 foreach ($options as $option) {
00141 if ($option->getSelections()) {
00142
00143 $selectionMinimalPrices = array();
00144 $selectionMaximalPrices = array();
00145
00146 foreach ($option->getSelections() as $selection) {
00147 if (!$selection->isSalable()) {
00148 continue;
00149 }
00150
00151 $qty = $selection->getSelectionQty();
00152 if ($selection->getSelectionCanChangeQty() && $option->getType() != 'multi' && $option->getType() != 'checkbox') {
00153 $qty = min(1, $qty);
00154 }
00155
00156 $selectionMinimalPrices[] = $this->getSelectionPrice($product, $selection, $qty);
00157 $selectionMaximalPrices[] = $this->getSelectionPrice($product, $selection);
00158 }
00159
00160 if (count($selectionMinimalPrices)) {
00161 if ($option->getRequired()) {
00162 $minimalPrice += min($selectionMinimalPrices);
00163 }
00164
00165 if ($option->isMultiSelection()) {
00166 $maximalPrice += array_sum($selectionMaximalPrices);
00167 } else {
00168 $maximalPrice += max($selectionMaximalPrices);
00169 }
00170 }
00171 }
00172 }
00173 }
00174
00175
00176
00177
00178 if ($customOptions = $product->getOptions()) {
00179 foreach ($customOptions as $customOption) {
00180 if ($values = $customOption->getValues()) {
00181 $prices = array();
00182 foreach ($values as $value) {
00183 $prices[] = $value->getPrice();
00184 }
00185 if (count($prices)) {
00186 var_dump($prices);
00187 if ($customOption->getIsRequire()) {
00188 $minimalPrice += min($prices);
00189 }
00190 $maximalPrice += max($prices);
00191 }
00192 } else {
00193 if ($customOption->getIsRequire()) {
00194 $minimalPrice += $customOption->getPrice();
00195 }
00196 $maximalPrice += $customOption->getPrice();
00197 }
00198 }
00199 }
00200 }
00201 if (is_null($which)) {
00202 return array($minimalPrice, $maximalPrice);
00203 } else if ($which = 'max') {
00204 return $maximalPrice;
00205 } else if ($which = 'min') {
00206 return $minimalPrice;
00207 }
00208 return 0;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 public function getMinimalPrice($product)
00218 {
00219 return $this->getPrices($product, 'min');
00220 }
00221
00222
00223
00224
00225
00226
00227
00228 public function getMaximalPrice($product)
00229 {
00230 return $this->getPrice($product, 'max');
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 public function getOptions($product)
00240 {
00241 $product->getTypeInstance(true)
00242 ->setStoreFilter($product->getStoreId(), $product);
00243
00244 $optionCollection = $product->getTypeInstance(true)
00245 ->getOptionsCollection($product);
00246
00247 $selectionCollection = $product->getTypeInstance(true)
00248 ->getSelectionsCollection(
00249 $product->getTypeInstance(true)->getOptionsIds($product),
00250 $product
00251 );
00252
00253 return $optionCollection->appendSelections($selectionCollection, false, false);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 public function getSelectionPrice($bundleProduct, $selectionProduct, $selectionQty = null, $multiplyQty = true)
00265 {
00266 if (is_null($selectionQty)) {
00267 $selectionQty = $selectionProduct->getSelectionQty();
00268 }
00269
00270 if ($bundleProduct->getPriceType() == self::PRICE_TYPE_DYNAMIC) {
00271 if ($multiplyQty) {
00272 $selectionPrice = $selectionProduct->getFinalPrice($selectionQty) * $selectionQty;
00273 } else {
00274 $selectionPrice = $selectionProduct->getFinalPrice($selectionQty);
00275 }
00276 return $selectionPrice;
00277 } else {
00278 if ($selectionProduct->getSelectionPriceType()) {
00279 return ($bundleProduct->getPrice()*$selectionProduct->getSelectionPriceValue()/100)*$selectionQty;
00280 } else {
00281 return $selectionProduct->getSelectionPriceValue()*$selectionQty;
00282 }
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 public function getSelectionPreFinalPrice($bundleProduct, $selectionProduct, $qty = null)
00295 {
00296 return $this->_applySpecialPrice($bundleProduct, $this->getSelectionPrice($bundleProduct, $selectionProduct, $qty));
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 public function getSelectionFinalPrice($bundleProduct, $selectionProduct, $bundleQty, $selectionQty = null, $multiplyQty = true)
00310 {
00311 $selectionPrice = $this->getSelectionPrice($bundleProduct, $selectionProduct, $selectionQty, $multiplyQty);
00312
00313 $tierPrice = $this->_applyTierPrice($bundleProduct, $bundleQty, $selectionPrice);
00314
00315
00316 $specialPrice = $this->_applySpecialPrice($bundleProduct, $selectionPrice);
00317
00318 return min(array($tierPrice, $specialPrice));
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 protected function _applyTierPrice($product, $qty, $finalPrice)
00330 {
00331 if (is_null($qty)) {
00332 return $finalPrice;
00333 }
00334
00335 $tierPrice = $product->getTierPrice($qty);
00336 if (is_numeric($tierPrice)) {
00337 $tierPrice = $finalPrice - ($finalPrice*$tierPrice)/100;
00338 $finalPrice = min($finalPrice, $tierPrice);
00339 }
00340 return $finalPrice;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350 public function getTierPrice($qty=null, $product)
00351 {
00352 $allGroups = Mage_Customer_Model_Group::CUST_GROUP_ALL;
00353 $prices = $product->getData('tier_price');
00354
00355 if (is_null($prices)) {
00356 if ($attribute = $product->getResource()->getAttribute('tier_price')) {
00357 $attribute->getBackend()->afterLoad($product);
00358 $prices = $product->getData('tier_price');
00359 }
00360 }
00361
00362 if (is_null($prices) || !is_array($prices)) {
00363 if (!is_null($qty)) {
00364 return $product->getPrice();
00365 }
00366 return array(array(
00367 'price' => $product->getPrice(),
00368 'website_price' => $product->getPrice(),
00369 'price_qty' => 1,
00370 'cust_group' => $allGroups,
00371 ));
00372 }
00373
00374 $custGroup = $this->_getCustomerGroupId($product);
00375 if ($qty) {
00376 $prevQty = 1;
00377 $prevPrice = 0;
00378 $prevGroup = $allGroups;
00379
00380 foreach ($prices as $price) {
00381 if ($price['cust_group']!=$custGroup && $price['cust_group']!=$allGroups) {
00382
00383 continue;
00384 }
00385 if ($qty < $price['price_qty']) {
00386
00387 continue;
00388 }
00389 if ($price['price_qty'] < $prevQty) {
00390
00391 continue;
00392 }
00393 if ($price['price_qty'] == $prevQty && $prevGroup != $allGroups && $price['cust_group'] == $allGroups) {
00394
00395 continue;
00396 }
00397 $prevPrice = $price['website_price'];
00398 $prevQty = $price['price_qty'];
00399 $prevGroup = $price['cust_group'];
00400 }
00401 return $prevPrice;
00402 } else {
00403 foreach ($prices as $i=>$price) {
00404 if ($price['cust_group']!=$custGroup && $price['cust_group']!=$allGroups) {
00405 unset($prices[$i]);
00406 }
00407 }
00408 }
00409
00410 return ($prices) ? $prices : array();
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 public static function calculatePrice($basePrice, $specialPrice, $specialPriceFrom, $specialPriceTo, $rulePrice = false, $wId = null, $gId = null, $productId = null)
00427 {
00428 $resource = Mage::getResourceSingleton('bundle/bundle');
00429 $selectionResource = Mage::getResourceSingleton('bundle/selection');
00430 $productPriceTypeId = Mage::getSingleton('eav/entity_attribute')->getIdByCode('catalog_product', 'price_type');
00431
00432 if ($wId instanceof Mage_Core_Model_Store) {
00433 $store = $wId->getId();
00434 $wId = $wId->getWebsiteId();
00435 } else {
00436 $store = Mage::app()->getStore($wId)->getId();
00437 $wId = Mage::app()->getStore($wId)->getWebsiteId();
00438
00439 }
00440
00441 if (!$gId) {
00442 $gId = Mage::getSingleton('customer/session')->getCustomerGroupId();
00443 } else if ($gId instanceof Mage_Customer_Model_Group) {
00444 $gId = $gId->getId();
00445 }
00446
00447 if (!isset(self::$attributeCache[$productId]['price_type'])) {
00448 $attributes = $resource->getAttributeData($productId, $productPriceTypeId, $store);
00449 self::$attributeCache[$productId]['price_type'] = $attributes;
00450 } else {
00451 $attributes = self::$attributeCache[$productId]['price_type'];
00452 }
00453
00454 $options = array(0);
00455 $results = $resource->getSelectionsData($productId);
00456
00457 if (!$attributes || !$attributes[0]['value']) {
00458 foreach ($results as $result) {
00459 if (!$result['product_id']) {
00460 continue;
00461 }
00462
00463 if ($result['selection_can_change_qty'] && $result['type'] != 'multi' && $result['type'] != 'checkbox') {
00464 $qty = 1;
00465 } else {
00466 $qty = $result['selection_qty'];
00467 }
00468
00469 $result['final_price'] = $selectionResource->getPriceFromIndex($result['product_id'], $qty, $store, $gId);
00470
00471 $selectionPrice = $result['final_price']*$qty;
00472
00473 if (isset($options[$result['option_id']])) {
00474 $options[$result['option_id']] = min($options[$result['option_id']], $selectionPrice);
00475 } else {
00476 $options[$result['option_id']] = $selectionPrice;
00477 }
00478 }
00479 $basePrice = array_sum($options);
00480 }
00481 else {
00482 foreach ($results as $result) {
00483 if (!$result['product_id']) {
00484 continue;
00485 }
00486 if ($result['selection_price_type']) {
00487 $selectionPrice = $basePrice*$result['selection_price_value']/100;
00488 } else {
00489 $selectionPrice = $result['selection_price_value'];
00490 }
00491
00492 if ($result['selection_can_change_qty'] && $result['type'] != 'multi' && $result['type'] != 'checkbox') {
00493 $qty = 1;
00494 } else {
00495 $qty = $result['selection_qty'];
00496 }
00497
00498 $selectionPrice = $selectionPrice*$qty;
00499
00500 if (isset($options[$result['option_id']])) {
00501 $options[$result['option_id']] = min($options[$result['option_id']], $selectionPrice);
00502 } else {
00503 $options[$result['option_id']] = $selectionPrice;
00504 }
00505 }
00506
00507 $basePrice = $basePrice + array_sum($options);
00508 }
00509
00510 $finalPrice = self::calculateSpecialPrice($basePrice, $specialPrice, $specialPriceFrom, $specialPriceTo, $store);
00511
00512
00513
00514
00515 $customOptions = Mage::getResourceSingleton('catalog/product_option_collection')->reset();
00516 $customOptions->addFieldToFilter('is_require', '1')
00517 ->addProductToFilter($productId)
00518 ->addPriceToResult($store, 'price')
00519 ->addValuesToResult();
00520
00521 foreach ($customOptions as $customOption) {
00522 if ($values = $customOption->getValues()) {
00523 $prices = array();
00524 foreach ($values as $value) {
00525 $prices[] = $value->getPrice();
00526 }
00527 if (count($prices)) {
00528 $finalPrice += min($prices);
00529 }
00530 } else {
00531 $finalPrice += $customOption->getPrice();
00532 }
00533 }
00534
00535 if ($rulePrice === false) {
00536 $rulePrice = Mage::getResourceModel('catalogrule/rule')->getRulePrice(Mage::app()->getLocale()->storeTimeStamp($store), $wId, $gId, $productId);
00537 }
00538
00539 if ($rulePrice !== null && $rulePrice !== false) {
00540 $finalPrice = min($finalPrice, $rulePrice);
00541 }
00542
00543 $finalPrice = max($finalPrice, 0);
00544
00545 return $finalPrice;
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 public static function calculateSpecialPrice($finalPrice, $specialPrice, $specialPriceFrom, $specialPriceTo, $store = null)
00559 {
00560 if (!is_null($specialPrice) && $specialPrice != false) {
00561 if (Mage::app()->getLocale()->IsStoreDateInInterval($store, $specialPriceFrom, $specialPriceTo)) {
00562 $specialPrice = ($finalPrice * $specialPrice) / 100;
00563 $finalPrice = min($finalPrice, $specialPrice);
00564 }
00565 }
00566 return $finalPrice;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 }