oxbasket.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxBasket extends oxSuperCfg
00008 {
00014     protected $_aBasketContents = array();
00015 
00021     protected $_iProductsCnt = 0;
00022 
00028     protected $_dItemsCnt = 0.0;
00029 
00035     protected $_dWeight = 0.0;
00036 
00042     protected $_oPrice = null;
00043 
00049     protected $_isCalculationModeNetto = null;
00050 
00056     protected $_dNettoSum = null;
00057 
00063     protected $_dBruttoSum = null;
00064 
00070     protected $_oProductsPriceList = null;
00071 
00077     protected $_aDiscounts = array();
00078 
00084     protected $_aItemDiscounts = array();
00085 
00091     protected $_sOrderId = null;
00092 
00098     protected $_aVouchers = array();
00099 
00105     protected $_aCosts = array();
00106 
00112     protected $_oDiscountProductsPriceList = null;
00113 
00119     protected $_oNotDiscountedProductsPriceList = null;
00120 
00126     protected $_blUpdateNeeded = true;
00127 
00133     protected $_aBasketSummary = null;
00134 
00140     protected $_sPaymentId = null;
00141 
00147     protected $_sShippingSetId = null;
00148 
00154     protected $_oUser = null;
00155 
00161     protected $_oTotalDiscount = null;
00162 
00168     protected $_oVoucherDiscount = null;
00169 
00175     protected $_oCurrency = null;
00176 
00182     protected $_blSkipVouchersAvailabilityChecking = null;
00183 
00189     protected $_dDiscountedProductNettoPrice = null;
00190 
00196     protected $_aDiscountedVats = null;
00197 
00203     protected $_blSkipDiscounts = false;
00204 
00210     protected $_oDeliveryPrice = null;
00211 
00217      protected $_blCheckStock = true;
00218 
00224     protected $_blCalcDiscounts = true;
00225 
00231     protected $_sBasketCategoryId = null;
00232 
00238     protected $_blShowCatChangeWarning = false;
00239 
00245     protected $_sTsProductId = null;
00246 
00251     protected $_blNewITemAdded = null;
00252 
00257     protected $_blDownloadableProducts = null;
00258 
00259 
00265     public function isCalculationModeNetto()
00266     {
00267         if ( $this->_isCalculationModeNetto === null ) {
00268             $this->setCalculationModeNetto( $this->isPriceViewModeNetto() );
00269         }
00270 
00271         return $this->_isCalculationModeNetto;
00272     }
00273 
00281     public function setCalculationModeNetto( $blNettoMode = true )
00282     {
00283         $this->_isCalculationModeNetto = (bool) $blNettoMode;
00284     }
00285 
00291     public function getNettoSum()
00292     {
00293         return $this->_dNettoSum;
00294     }
00295 
00301     public function getBruttoSum()
00302     {
00303         return $this->_dBruttoSum;
00304     }
00305 
00313     public function setNettoSum( $dNettoSum )
00314     {
00315         $this->_dNettoSum = $dNettoSum;
00316     }
00317 
00325     public function setBruttoSum( $dBruttoSum )
00326     {
00327         $this->_dBruttoSum = $dBruttoSum;
00328     }
00329 
00335     public function isEnabled()
00336     {
00337         return !oxRegistry::getUtils()->isSearchEngine();
00338     }
00339 
00349     protected function _changeBasketItemKey($sOldKey, $sNewKey, $value = null)
00350     {
00351         reset($this->_aBasketContents);
00352         $iOldKeyPlace = 0;
00353         while (key($this->_aBasketContents) != $sOldKey && next($this->_aBasketContents)) {
00354             ++$iOldKeyPlace;
00355         }
00356         $aNewCopy = array_merge(
00357             array_slice($this->_aBasketContents, 0, $iOldKeyPlace, true),
00358             array($sNewKey => $value),
00359             array_slice($this->_aBasketContents, $iOldKeyPlace+1, count($this->_aBasketContents)-$iOldKeyPlace, true)
00360         );
00361         $this->_aBasketContents = $aNewCopy;
00362     }
00363 
00379     public function addToBasket( $sProductID, $dAmount, $aSel = null, $aPersParam = null, $blOverride = false, $blBundle = false, $sOldBasketItemId = null )
00380     {
00381         // enabled ?
00382         if ( !$this->isEnabled() )
00383             return null;
00384 
00385         // basket exclude
00386         if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' ) ) {
00387             if ( !$this->canAddProductToBasket( $sProductID ) ) {
00388                 $this->setCatChangeWarningState( true );
00389                 return null;
00390             } else {
00391                 $this->setCatChangeWarningState( false );
00392             }
00393         }
00394 
00395         $sItemId = $this->getItemKey( $sProductID, $aSel, $aPersParam, $blBundle );
00396         if ( $sOldBasketItemId && ( strcmp( $sOldBasketItemId, $sItemId ) != 0 ) ) {
00397             if ( isset( $this->_aBasketContents[$sItemId] ) ) {
00398                 // we are merging, so params will just go to the new key
00399                 unset( $this->_aBasketContents[$sOldBasketItemId] );
00400                 // do not override stock
00401                 $blOverride = false;
00402             } else {
00403                 // value is null - means isset will fail and real values will be filled
00404                 $this->_changeBasketItemKey( $sOldBasketItemId, $sItemId );
00405             }
00406         }
00407 
00408         // after some checks item must be removed from basket
00409         $blRemoveItem = false;
00410 
00411         // initialting exception storage
00412         $oEx = null;
00413 
00414         if ( isset( $this->_aBasketContents[$sItemId] ) ) {
00415 
00416             //updating existing
00417             try {
00418                 // setting stock check status
00419                 $this->_aBasketContents[$sItemId]->setStockCheckStatus( $this->getStockCheckMode() );
00420                 //validate amount
00421                 //possibly throws exception
00422                 $this->_aBasketContents[$sItemId]->setAmount( $dAmount, $blOverride, $sItemId );
00423             } catch( oxOutOfStockException $oEx ) {
00424                 // rethrow later
00425             }
00426 
00427         } else {
00428             //inserting new
00429             $oBasketItem = oxNew( 'oxbasketitem' );
00430             try {
00431                 $oBasketItem->setStockCheckStatus( $this->getStockCheckMode() );
00432                 $oBasketItem->init( $sProductID, $dAmount, $aSel, $aPersParam, $blBundle );
00433             } catch( oxNoArticleException $oEx ) {
00434                 // in this case that the article does not exist remove the item from the basket by setting its amount to 0
00435                 //$oBasketItem->dAmount = 0;
00436                 $blRemoveItem = true;
00437 
00438             } catch( oxOutOfStockException $oEx ) {
00439                 // rethrow later
00440             } catch ( oxArticleInputException $oEx ) {
00441                 // rethrow later
00442                 $blRemoveItem = true;
00443             }
00444 
00445             $this->_aBasketContents[$sItemId] = $oBasketItem;
00446         }
00447 
00448         //in case amount is 0 removing item
00449         if ( $this->_aBasketContents[$sItemId]->getAmount() == 0 || $blRemoveItem ) {
00450             $this->removeItem( $sItemId );
00451         } elseif ( $blBundle ) {
00452             //marking bundles
00453             $this->_aBasketContents[$sItemId]->setBundle( true );
00454         }
00455 
00456         //calling update method
00457         $this->onUpdate();
00458 
00459         if ( $oEx ) {
00460             throw $oEx;
00461         }
00462 
00463         // notifying that new basket item was added
00464         $this->_addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId );
00465 
00466         // returning basket item object
00467         return $this->_aBasketContents[$sItemId];
00468     }
00469 
00477     public function addOrderArticleToBasket( $oOrderArticle )
00478     {
00479         // adding only if amount > 0
00480         if ( $oOrderArticle->oxorderarticles__oxamount->value > 0 && !$oOrderArticle->isBundle() ) {
00481             $sItemId = $oOrderArticle->getId();
00482 
00483             //inserting new
00484             $this->_aBasketContents[$sItemId] = oxNew( 'oxbasketitem' );
00485             $this->_aBasketContents[$sItemId]->initFromOrderArticle( $oOrderArticle );
00486             $this->_aBasketContents[$sItemId]->setWrapping( $oOrderArticle->oxorderarticles__oxwrapid->value );
00487             $this->_aBasketContents[$sItemId]->setBundle( $oOrderArticle->isBundle() );
00488 
00489             //calling update method
00490             $this->onUpdate();
00491 
00492             return $this->_aBasketContents[$sItemId];
00493         } elseif ( $oOrderArticle->isBundle() ) {
00494             // deleting bundles, they are handled automatically
00495             $oOrderArticle->delete();
00496         }
00497     }
00498 
00506     public function setStockCheckMode( $blCheck )
00507     {
00508         $this->_blCheckStock = $blCheck;
00509     }
00510 
00516     public function getStockCheckMode()
00517     {
00518         return $this->_blCheckStock;
00519     }
00520 
00533     public function getItemKey( $sProductId, $aSel = null, $aPersParam = null, $blBundle = false, $sAdditionalParam = '' )
00534     {
00535         $aSel = ( $aSel != null) ? $aSel : array (0=>'0');
00536 
00537         $sItemKey = md5( $sProductId.'|'.serialize( $aSel ).'|'.serialize( $aPersParam ).'|'.( int ) $blBundle . '|' . serialize( $sAdditionalParam ) );
00538 
00539         return $sItemKey;
00540     }
00541 
00542 
00550     public function removeItem( $sItemKey )
00551     {
00552         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
00553             if (isset($this->_aBasketContents[$sItemKey])) {
00554                 $sArticleId = $this->_aBasketContents[$sItemKey]->getProductId();
00555                 if ($sArticleId) {
00556                     $this->getSession()
00557                             ->getBasketReservations()
00558                             ->discardArticleReservation($sArticleId);
00559                 }
00560             }
00561         }
00562         unset( $this->_aBasketContents[$sItemKey] );
00563 
00564         // basket exclude
00565         if ( !count($this->_aBasketContents) && $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' ) ) {
00566             $this->setBasketRootCatId(null);
00567         }
00568     }
00569 
00575     protected function _clearBundles()
00576     {
00577         reset( $this->_aBasketContents );
00578         while ( list( $sItemKey, $oBasketItem ) = each( $this->_aBasketContents ) ) {
00579             if ( $oBasketItem->isBundle() ) {
00580                 $this->removeItem( $sItemKey );
00581             }
00582         }
00583     }
00584 
00592     protected function _getArticleBundles( $oBasketItem )
00593     {
00594         $aBundles = array();
00595 
00596         if ( $oBasketItem->isBundle() ) {
00597             return $aBundles;
00598         }
00599 
00600         $oArticle = $oBasketItem->getArticle( true );
00601         if ( $oArticle && $oArticle->oxarticles__oxbundleid->value ) {
00602             $aBundles[$oArticle->oxarticles__oxbundleid->value] = 1;
00603         }
00604 
00605         return $aBundles;
00606     }
00607 
00616     protected function _getItemBundles( $oBasketItem, $aBundles = array() )
00617     {
00618         if ( $oBasketItem->isBundle() ) {
00619             return array();
00620         }
00621 
00622         // does this object still exists ?
00623         if ( $oArticle = $oBasketItem->getArticle() ) {
00624             $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketItemBundleDiscounts( $oArticle, $this, $this->getBasketUser() );
00625 
00626             foreach ( $aDiscounts as $oDiscount ) {
00627 
00628                 $iAmnt = $oDiscount->getBundleAmount( $oBasketItem->getAmount() );
00629                 if ( $iAmnt ) {
00630                     //init array element
00631                     if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00632                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00633                     }
00634 
00635                     if ($oDiscount->oxdiscount__oxitmmultiple->value) {
00636                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $iAmnt;
00637                     } else {
00638                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = $iAmnt;
00639                     }
00640                 }
00641             }
00642         }
00643 
00644         return $aBundles;
00645     }
00646 
00654     protected function _getBasketBundles( $aBundles = array() )
00655     {
00656         $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketBundleDiscounts( $this, $this->getBasketUser() );
00657 
00658         // calculating amount of non bundled/discount items
00659         $dAmount = 0;
00660         foreach ( $this->_aBasketContents as $oBasketItem ) {
00661             if ( !( $oBasketItem->isBundle() || $oBasketItem->isDiscountArticle() ) ) {
00662                 $dAmount += $oBasketItem->getAmount();
00663             }
00664         }
00665 
00666         foreach ( $aDiscounts as $oDiscount ) {
00667             if ($oDiscount->oxdiscount__oxitmartid->value) {
00668                 if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00669                     $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00670                 }
00671 
00672                 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $oDiscount->getBundleAmount( $dAmount );
00673             }
00674         }
00675 
00676         return $aBundles;
00677     }
00678 
00685     protected function _addBundles()
00686     {
00687         $aBundles = array();
00688         // iterating through articles and binding bundles
00689         foreach ( $this->_aBasketContents as $key => $oBasketItem ) {
00690             try {
00691                 // adding discount type bundles
00692                 if ( !$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle() ) {
00693                     $aBundles = $this->_getItemBundles( $oBasketItem, $aBundles );
00694                 } else {
00695                     continue;
00696                 }
00697 
00698                     // adding item type bundles
00699                     $aArtBundles = $this->_getArticleBundles( $oBasketItem );
00700 
00701                     // adding bundles to basket
00702                     $this->_addBundlesToBasket( $aArtBundles );
00703             } catch ( oxNoArticleException $oEx ) {
00704                 $this->removeItem( $key );
00705                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00706             } catch( oxArticleInputException $oEx ) {
00707                 $this->removeItem( $key );
00708                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00709             }
00710         }
00711 
00712         // adding global basket bundles
00713         $aBundles = $this->_getBasketBundles( $aBundles );
00714 
00715         // adding all bundles to basket
00716         if ( $aBundles ) {
00717             $this->_addBundlesToBasket( $aBundles );
00718         }
00719     }
00720 
00728     protected function _addBundlesToBasket( $aBundles )
00729     {
00730         foreach ( $aBundles as $sBundleId => $dAmount ) {
00731             if ( $dAmount ) {
00732                 try {
00733                     if ( $oBundleItem = $this->addToBasket( $sBundleId, $dAmount, null, null, false, true ) ) {
00734                         $oBundleItem->setAsDiscountArticle( true );
00735                     }
00736                 } catch(oxArticleException $oEx) {
00737                     // caught and ignored
00738                 }
00739             }
00740         }
00741 
00742     }
00743 
00749     protected function _calcItemsPrice()
00750     {
00751         // resetting
00752         $this->setSkipDiscounts( false );
00753         $this->_iProductsCnt = 0; // count different types
00754         $this->_dItemsCnt    = 0; // count of item units
00755         $this->_dWeight      = 0; // basket weight
00756 
00757         $this->_oProductsPriceList = oxNew( 'oxpricelist' );
00758         $this->_oDiscountProductsPriceList = oxNew( 'oxpricelist' );
00759         $this->_oNotDiscountedProductsPriceList = oxNew( 'oxpricelist' );
00760 
00761         $oDiscountList = oxRegistry::get("oxDiscountList");
00762 
00763         foreach ( $this->_aBasketContents as $oBasketItem ) {
00764             $this->_iProductsCnt++;
00765             $this->_dItemsCnt += $oBasketItem->getAmount();
00766             $this->_dWeight   += $oBasketItem->getWeight();
00767 
00768             if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle( true ) ) ) {
00769 
00770                 $oBasketPrice = $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $this );
00771                 $oBasketItem->setRegularUnitPrice( clone $oBasketPrice );
00772 
00773                 if ( !$oArticle->skipDiscounts() && $this->canCalcDiscounts() ) {
00774                     // apply basket type discounts for item
00775                     $aDiscounts = $oDiscountList->getBasketItemDiscounts( $oArticle, $this, $this->getBasketUser() );
00776                     reset( $aDiscounts );
00777                     foreach ( $aDiscounts as $oDiscount ) {
00778                         $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
00779                     }
00780                     $oBasketPrice->calculateDiscount();
00781                 } else {
00782                     $oBasketItem->setSkipDiscounts( true );
00783                     $this->setSkipDiscounts( true );
00784                 }
00785 
00786                 $oBasketItem->setPrice( $oBasketPrice );
00787                 $this->_oProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00788 
00789                 //P collect discount values for basket items which are discountable
00790                 if ( !$oArticle->skipDiscounts() ) {
00791 
00792                     $this->_oDiscountProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00793                 } else {
00794                     $this->_oNotDiscountedProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00795                     $oBasketItem->setSkipDiscounts( true );
00796                     $this->setSkipDiscounts( true );
00797                 }
00798             } elseif ( $oBasketItem->isBundle() ) {
00799                 // if bundles price is set to zero
00800                 $oPrice = oxNew( "oxprice");
00801                 $oBasketItem->setPrice( $oPrice );
00802             }
00803         }
00804     }
00805 
00813     public function setDiscountCalcMode( $blCalcDiscounts )
00814     {
00815         $this->_blCalcDiscounts = $blCalcDiscounts;
00816     }
00817 
00823     public function canCalcDiscounts()
00824     {
00825         return $this->_blCalcDiscounts;
00826     }
00827 
00837     protected function _mergeDiscounts( $aDiscounts, $aItemDiscounts)
00838     {
00839         foreach ( $aItemDiscounts as $sKey => $oDiscount ) {
00840             // add prices of the same discounts
00841             if ( array_key_exists ($sKey, $aDiscounts) ) {
00842                 $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
00843             } else {
00844                 $aDiscounts[$sKey] = $oDiscount;
00845             }
00846         }
00847         return $aDiscounts;
00848     }
00849 
00855     protected function _calcDeliveryCost()
00856     {
00857         if ( $this->_oDeliveryPrice !== null ) {
00858             return $this->_oDeliveryPrice;
00859         }
00860         $myConfig  = $this->getConfig();
00861         $oDeliveryPrice = oxNew( 'oxprice' );
00862 
00863         if ( $this->getConfig()->getConfigParam( 'blDeliveryVatOnTop' ) ) {
00864             $oDeliveryPrice->setNettoPriceMode();
00865         } else {
00866             $oDeliveryPrice->setBruttoPriceMode();
00867         }
00868 
00869         // don't calculate if not logged in
00870         $oUser = $this->getBasketUser();
00871 
00872         if ( !$oUser && !$myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) {
00873             return $oDeliveryPrice;
00874         }
00875 
00876         // VAT for delivery will be calculated always (#3757)
00877         // blCalcVATForDelivery option is @deprecated since 2012-03-23 in version 4.6
00878         // the option blShowVATForDelivery will be used only for displaying
00879         $fDelVATPercent = 0;
00880         $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00881         $oDeliveryPrice->setVat( $fDelVATPercent );
00882 
00883         // list of active delivery costs
00884         if ( $myConfig->getConfigParam('bl_perfLoadDelivery') ) {
00885             $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList( $this,
00886                                         $oUser,
00887                                         $this->_findDelivCountry(),
00888                                         $this->getShippingId()
00889                                     );
00890 
00891             if ( count( $aDeliveryList ) > 0 ) {
00892                 foreach ( $aDeliveryList as $oDelivery ) {
00893                     //debug trace
00894                     if ( $myConfig->getConfigParam( 'iDebug' ) == 5 ) {
00895                         echo( "DelCost : ".$oDelivery->oxdelivery__oxtitle->value."<br>" );
00896                     }
00897                     $oDeliveryPrice->addPrice( $oDelivery->getDeliveryPrice( $fDelVATPercent ) );
00898                 }
00899             }
00900         }
00901 
00902         return $oDeliveryPrice;
00903     }
00904 
00910     public function getBasketUser()
00911     {
00912         if ( $this->_oUser == null ) {
00913             return $this->getUser();
00914         }
00915 
00916         return $this->_oUser;
00917     }
00918 
00926     public function setBasketUser( $oUser )
00927     {
00928         $this->_oUser = $oUser;
00929     }
00930 
00931     //P
00937     public function getMostUsedVatPercent()
00938     {
00939         if ( $this->_oProductsPriceList ) {
00940             return $this->_oProductsPriceList->getMostUsedVatPercent();
00941         }
00942     }
00943 
00949     public function getAdditionalServicesVatPercent()
00950     {
00951         if ( $this->_oProductsPriceList ) {
00952             if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional') {
00953                 return $this->_oProductsPriceList->getProportionalVatPercent();
00954             } else {
00955                 return $this->_oProductsPriceList->getMostUsedVatPercent();
00956             }
00957         }
00958     }
00959 
00965     public function isProportionalCalculationOn()
00966     {
00967         if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional' ) {
00968             return true;
00969         }
00970         return false;
00971     }
00972 
00973 
00974  //P
00981     protected function _calcTotalPrice()
00982     {
00983         // 1. add products price
00984         $dprice = $this->_dBruttoSum;//$this->_oProductsPriceList->getBruttoSum();
00985         $this->_oPrice = oxNew( 'oxPrice' );
00986         $this->_oPrice->setBruttoPriceMode();
00987         $this->_oPrice->setPrice( $dprice );
00988 
00989         // 2. substract discounts
00990         if ( $dprice && !$this->isCalculationModeNetto() ) {
00991 
00992             // 2.1 applying basket item discounts
00993             /*foreach ( $this->_aItemDiscounts as $oDiscount ) {
00994 
00995                 // skipping bundle discounts
00996                 if ( $oDiscount->sType == 'itm' ) {
00997                     continue;
00998                 }
00999                 $this->_oPrice->subtract( $oDiscount->dDiscount );
01000             }*/
01001 
01002             // 2.2 applying basket discounts
01003             $this->_oPrice->subtract( $this->_oTotalDiscount->getBruttoPrice() );
01004 
01005             // 2.3 applying voucher discounts
01006             if ($oVoucherDisc = $this->getVoucherDiscount()) {
01007                 $this->_oPrice->subtract( $oVoucherDisc->getBruttoPrice() );
01008             }
01009         }
01010 
01011         // 2.3 add delivery cost
01012         if ( isset( $this->_aCosts['oxdelivery'] ) ) {
01013             $this->_oPrice->add( $this->_aCosts['oxdelivery']->getBruttoPrice() );
01014         }
01015 
01016         // 2.4 add wrapping price
01017         if ( isset( $this->_aCosts['oxwrapping'] ) ) {
01018             $this->_oPrice->add( $this->_aCosts['oxwrapping']->getBruttoPrice() );
01019         }
01020         if ( isset( $this->_aCosts['oxgiftcard'] ) ) {
01021             $this->_oPrice->add( $this->_aCosts['oxgiftcard']->getBruttoPrice() );
01022         }
01023 
01024         // 2.5 add payment price
01025         if ( isset( $this->_aCosts['oxpayment'] ) ) {
01026             $this->_oPrice->add( $this->_aCosts['oxpayment']->getBruttoPrice() );
01027         }
01028 
01029         // 2.6 add TS protection price
01030         if ( isset( $this->_aCosts['oxtsprotection'] ) ) {
01031             $this->_oPrice->add( $this->_aCosts['oxtsprotection']->getBruttoPrice() );
01032         }
01033 
01034     }
01035 
01043     public function setVoucherDiscount( $dDiscount )
01044     {
01045         $this->_oVoucherDiscount = oxNew( 'oxPrice' );
01046         $this->_oVoucherDiscount->setBruttoPriceMode();
01047         $this->_oVoucherDiscount->add( $dDiscount );
01048     }
01049 
01055     protected function _calcVoucherDiscount()
01056     {
01057         if ( $this->getConfig()->getConfigParam( 'bl_showVouchers' ) && ($this->_oVoucherDiscount === null || ( $this->_blUpdateNeeded && !$this->isAdmin() ) ) ) {
01058 
01059             $this->_oVoucherDiscount = $this->_getPriceObject();
01060 
01061             // calculating price to apply discount
01062             $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() ) - $this->_oTotalDiscount->getPrice();
01063 
01064             // recalculating
01065             if ( count( $this->_aVouchers ) ) {
01066                 $oLang = oxRegistry::getLang();
01067                 foreach ( $this->_aVouchers as $sVoucherId => $oStdVoucher ) {
01068                     $oVoucher = oxNew( 'oxvoucher' );
01069                     try { // checking
01070                         $oVoucher->load( $oStdVoucher->sVoucherId );
01071 
01072                         if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01073                             $oVoucher->checkBasketVoucherAvailability( $this->_aVouchers, $dPrice );
01074                             $oVoucher->checkUserAvailability( $this->getBasketUser() );
01075                         }
01076 
01077                         // assigning real voucher discount value as this is the only place where real value is calculated
01078                         $dVoucherdiscount = $oVoucher->getDiscountValue( $dPrice );
01079 
01080                         if ( $dVoucherdiscount > 0 ) {
01081 
01082                             if ( $oVoucher->getDiscountType() == 'absolute' ) {
01083                                 $dVatPart = ( $dPrice - $dVoucherdiscount ) / $dPrice * 100;
01084                             } else {
01085                                 $dVatPart = 100 - $oVoucher->getDiscount();
01086                             }
01087 
01088                             if ( !$this->_aDiscountedVats ) {
01089                                 if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01090                                     $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01091                                 }
01092                             }
01093 
01094                             // applay discout to vat
01095                             foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01096                                 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01097                             }
01098                         }
01099 
01100                         // acumulating discount value
01101                         $this->_oVoucherDiscount->add( $dVoucherdiscount );
01102 
01103                         // collecting formatted for preview
01104                         $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency( $dVoucherdiscount, $this->getBasketCurrency() );
01105                         $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01106 
01107                         // substracting voucher discount
01108                         $dPrice = $dPrice - $dVoucherdiscount;
01109 
01110 
01111 
01112                     } catch ( oxVoucherException $oEx ) {
01113 
01114                         // removing voucher on error
01115                         $oVoucher->unMarkAsReserved();
01116                         unset( $this->_aVouchers[$sVoucherId] );
01117 
01118                         // storing voucher error info
01119                         oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01120                     }
01121                 }
01122             }
01123         }
01124     }
01125 
01132     protected function _applyDiscounts()
01133     {
01134         $dBruttoPrice = 0;
01135 
01136         //apply discounts for brutto price
01137         $dDiscountedBruttoPrice = $this->_getDiscountedProductsSum();
01138         $oTotalDiscount   = $this->getTotalDiscount();
01139         $oVoucherDiscount = $this->getVoucherDiscount();
01140 
01141         $oUtils = oxRegistry::getUtils();
01142         $dVatSum = 0;
01143         foreach ( $this->_aDiscountedVats as $dVat ) {
01144             $dVatSum +=  $oUtils->fRound( $dVat, $this->_oCurrency);
01145         }
01146 
01147         $oNotDiscounted = $this->getNotDiscountProductsPrice();
01148 
01149         if ( $this->isCalculationModeNetto() ) {
01150             // netto view mode
01151             $this->setNettoSum($this->getProductsPrice()->getSum());
01152             $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedBruttoPrice + $dVatSum);
01153         } else {
01154             // brutto view mode
01155             $this->setNettoSum( $oNotDiscounted->getSum() + $dDiscountedBruttoPrice - $dVatSum );
01156             $this->setBruttoSum( $this->getProductsPrice()->getSum(false) );
01157         }
01158     }
01164     public function isPriceViewModeNetto()
01165     {
01166         $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
01167         $oUser = $this->getBasketUser();
01168         if ( $oUser ) {
01169             $blResult = $oUser->isPriceViewModeNetto();
01170         }
01171 
01172         return $blResult;
01173     }
01174 
01180     protected function _getPriceObject()
01181     {
01182         $oPrice = oxNew( 'oxPrice' );
01183 
01184         if ( $this->isCalculationModeNetto() ) {
01185             $oPrice->setNettoPriceMode();
01186         } else {
01187             $oPrice->setBruttoPriceMode();
01188         }
01189 
01190         return $oPrice;
01191     }
01192 
01198     protected function _calcBasketDiscount()
01199     {
01200         // resetting
01201         $this->_aDiscounts = array();
01202 
01203         // P using prices sum which has discount, not sum of skipped discounts
01204         $dOldprice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01205 
01206         // add basket discounts
01207         $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts( $this, $this->getBasketUser() );
01208         if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01209             $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01210         }
01211 
01212         foreach ( $aDiscounts as $oDiscount ) {
01213 
01214             // storing applied discounts
01215             $oStdDiscount = $oDiscount->getSimpleDiscount();
01216 
01217             // skipping bundle discounts
01218             if ( $oDiscount->oxdiscount__oxaddsumtype->value == 'itm' ) {
01219                 continue;
01220             }
01221 
01222             // saving discount info
01223             $oStdDiscount->dDiscount = $oDiscount->getAbsValue( $dOldprice );
01224 
01225             //var_dump($oDiscount->getPercentage( $dOldprice ));
01226 
01227             $dVatPart = 100 - $oDiscount->getPercentage( $dOldprice );
01228 
01229             // if discoount is more than basket sum
01230             if ( $dOldprice < $oStdDiscount->dDiscount ) {
01231                 $oStdDiscount->dDiscount = $dOldprice;
01232                 $dVatPart = 0;
01233             }
01234 
01235             // applay discout to vat
01236             foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01237                 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01238             }
01239 
01240             //storring discount
01241             if ($oStdDiscount->dDiscount != 0) {
01242                 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01243                 // substracting product price after discount
01244                 $dOldprice = $dOldprice - $oStdDiscount->dDiscount;
01245             }
01246         }
01247     }
01248 
01254     protected function _calcBasketTotalDiscount()
01255     {
01256         if ( $this->_oTotalDiscount === null || ( !$this->isAdmin() ) ) {
01257 
01258             $this->_oTotalDiscount = $this->_getPriceObject();
01259 
01260             if ( is_array($this->_aDiscounts) ) {
01261                 foreach ( $this->_aDiscounts as $oDiscount ) {
01262 
01263                     // skipping bundle discounts
01264                     if ( $oDiscount->sType == 'itm' ) {
01265                         continue;
01266                     }
01267 
01268                     // add discount value to total basket discount
01269                     $this->_oTotalDiscount->add( $oDiscount->dDiscount );
01270                 }
01271             }
01272         }
01273     }
01274 
01283     protected function _calcBasketWrapping()
01284     {
01285         $oWrappingPrices = oxNew( 'oxPriceList' );
01286 
01287         foreach ( $this->_aBasketContents as $oBasketItem ) {
01288 
01289             if ( ( $oWrapping = $oBasketItem->getWrapping() ) ) {
01290 
01291                 $oWrappingPrice = $oWrapping->getWrappingPrice( $oBasketItem->getAmount() );
01292                 $oWrappingPrice->setVat( $oBasketItem->getPrice()->getVat() );
01293 
01294                 $oWrappingPrices->addToPriceList( $oWrappingPrice );
01295             }
01296         }
01297 
01298         if ( $oWrappingPrices->getCount() ) {
01299             $oWrappingCost = oxNew( 'oxPrice' );
01300             $oWrappingCost = $oWrappingPrices->calculateToPrice();
01301         }
01302 
01303         return $oWrappingCost;
01304     }
01305 
01314     protected function _calcBasketGiftCard()
01315     {
01316         $oGiftCardPrice = oxNew( 'oxPrice' );
01317 
01318         if ( $this->getConfig()->getConfigParam( 'blWrappingVatOnTop' ) ) {
01319             $oGiftCardPrice->setNettoPriceMode();
01320         } else {
01321             $oGiftCardPrice->setBruttoPriceMode();
01322         }
01323 
01324         $dVATPercent = $this->getAdditionalServicesVatPercent();
01325 
01326         $oGiftCardPrice->setVat( $dVATPercent );
01327 
01328         // gift card price calculation
01329         if ( ( $oCard = $this->getCard() ) ) {
01330             if ($dVATPercent !== null) {
01331                 $oCard->setWrappingVat($dVATPercent);
01332             }
01333             $oGiftCardPrice->addPrice( $oCard->getWrappingPrice() );
01334         }
01335 
01336         return $oGiftCardPrice;
01337     }
01338 
01345     protected function _calcPaymentCost()
01346     {
01347         // resetting values
01348         $oPaymentPrice = oxNew( 'oxPrice' );
01349 
01350         // payment
01351         if ( ( $this->_sPaymentId = $this->getPaymentId() ) ) {
01352 
01353             $oPayment = oxNew( 'oxpayment' );
01354             $oPayment->load( $this->_sPaymentId );
01355 
01356             $oPayment->calculate( $this );
01357             $oPaymentPrice = $oPayment->getPrice();
01358         }
01359 
01360         return $oPaymentPrice;
01361     }
01362 
01369     protected function _calcTsProtectionCost()
01370     {
01371         if ( ( $this->getTsProductId() ) ) {
01372             $oTsProtection = oxNew('oxtsprotection');
01373             $oTsProduct = $oTsProtection->getTsProduct( $this->getTsProductId() );
01374             $oProtectionPrice = $oTsProduct->getPrice();
01375             $oProtectionPrice->setVat( $this->getAdditionalServicesVatPercent() );
01376         } else {
01377             $oProtectionPrice = oxNew( 'oxPrice' );
01378         }
01379 
01380         return $oProtectionPrice;
01381     }
01382 
01391     public function setCost( $sCostName, $oPrice = null )
01392     {
01393         $this->_aCosts[$sCostName] = $oPrice;
01394     }
01395 
01404     public function calculateBasket( $blForceUpdate = false )
01405     {
01406         /*
01407         //would be good to perform the reset of previous calculation
01408         //at least you can use it for the debug
01409         $this->_aDiscounts = array();
01410         $this->_aItemDiscounts = array();
01411         $this->_oTotalDiscount = null;
01412         $this->_dDiscountedProductNettoPrice = 0;
01413         $this->_aDiscountedVats = array();
01414         $this->_oPrice = null;
01415         $this->_oNotDiscountedProductsPriceList = null;
01416         $this->_oProductsPriceList = null;
01417         $this->_oDiscountProductsPriceList = null;*/
01418 
01419 
01420         if ( !$this->isEnabled() ) {
01421             return;
01422         }
01423 
01424         if ( !$this->_blUpdateNeeded && !$blForceUpdate ) {
01425             return;
01426         }
01427 
01428         $this->_aCosts = array();
01429 
01430         //  1. saving basket to the database
01431         $this->_save();
01432 
01433         //  2. remove all bundles
01434         $this->_clearBundles();
01435 
01436         //  3. generate bundle items
01437         $this->_addBundles();
01438 
01439         // reserve active basket
01440         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01441             $this->getSession()->getBasketReservations()->reserveBasket($this);
01442         }
01443 
01444         //  4. calculating item prices
01445         $this->_calcItemsPrice();
01446 
01447         //  5. calculating/applying discounts
01448         $this->_calcBasketDiscount();
01449 
01450         //  6. calculating basket total discount
01451         $this->_calcBasketTotalDiscount();
01452 
01453         //  7. check for vouchers
01454         $this->_calcVoucherDiscount();
01455 
01456         //  8. applies all discounts to pricelist
01457         $this->_applyDiscounts();
01458 
01459         //  9. calculating additional costs:
01460         //  9.1: delivery
01461         $this->setCost( 'oxdelivery', $this->_calcDeliveryCost() );
01462 
01463         //  9.2: adding wrapping and giftcard costs
01464         $this->setCost( 'oxwrapping', $this->_calcBasketWrapping() );
01465 
01466         $this->setCost( 'oxgiftcard', $this->_calcBasketGiftCard() );
01467 
01468         //  9.3: adding payment cost
01469         $this->setCost( 'oxpayment', $this->_calcPaymentCost() );
01470 
01471         //  9.4: adding TS protection cost
01472         $this->setCost( 'oxtsprotection', $this->_calcTsProtectionCost() );
01473 
01474         //  10. calculate total price
01475         $this->_calcTotalPrice();
01476 
01477         //  11. formating discounts
01478         $this->formatDiscount();
01479 
01480         //  12.setting to up-to-date status
01481         $this->afterUpdate();
01482     }
01483 
01489     public function onUpdate()
01490     {
01491         $this->_blUpdateNeeded = true;
01492     }
01493 
01499     public function afterUpdate()
01500     {
01501         $this->_blUpdateNeeded = false;
01502     }
01503 
01511     public function getBasketSummary()
01512     {
01513         if ( $this->_blUpdateNeeded || $this->_aBasketSummary === null ) {
01514             $this->_aBasketSummary = new stdclass();
01515             $this->_aBasketSummary->aArticles = array();
01516             $this->_aBasketSummary->aCategories = array();
01517             $this->_aBasketSummary->iArticleCount = 0;
01518             $this->_aBasketSummary->dArticlePrice = 0;
01519             $this->_aBasketSummary->dArticleDiscountablePrice = 0;
01520         }
01521 
01522         if ( !$this->isEnabled() ) {
01523             return $this->_aBasketSummary;
01524         }
01525 
01526         $myConfig = $this->getConfig();
01527         foreach ( $this->_aBasketContents as $oBasketItem ) {
01528             if ( !$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false) ) {
01529                 $aCatIds = $oArticle->getCategoryIds();
01530                 //#M530 if price is not loaded for articles
01531                 $dPrice = 0;
01532                 $dDiscountablePrice = 0;
01533                 if ( ( $oPrice = $oArticle->getPrice( $oBasketItem->getAmount() ) ) ) {
01534                     $dPrice = $oPrice->getPrice();
01535                     if ( !$oArticle->skipDiscounts() ) {
01536                         $dDiscountablePrice = $dPrice;
01537                     }
01538                 }
01539 
01540                 foreach ( $aCatIds as $sCatId ) {
01541                     if ( !isset( $this->_aBasketSummary->aCategories[$sCatId] ) ) {
01542                         $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
01543                     }
01544 
01545                     $this->_aBasketSummary->aCategories[$sCatId]->dPrice  += $dPrice * $oBasketItem->getAmount();
01546                     $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01547                     $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
01548                     $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
01549                 }
01550 
01551                 // variant handling
01552                 if ( ($sParentId = $oArticle->getProductParentId()) && $myConfig->getConfigParam( 'blVariantParentBuyable' ) ) {
01553                     if ( !isset( $this->_aBasketSummary->aArticles[$sParentId] ) ) {
01554                         $this->_aBasketSummary->aArticles[$sParentId] = 0;
01555                     }
01556                     $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
01557                 }
01558 
01559                 if ( !isset( $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] ) ) {
01560                     $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
01561                 }
01562 
01563                 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
01564                 $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
01565                 $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
01566                 $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01567             }
01568         }
01569         return $this->_aBasketSummary;
01570     }
01571 
01583     public function addVoucher( $sVoucherId )
01584     {
01585         // calculating price to check
01586         // P using prices sum which has discount, not sum of skipped discounts
01587         $dPrice = 0;
01588         if ( $this->_oDiscountProductsPriceList ) {
01589             $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01590         }
01591 
01592         try { // trying to load voucher and apply it
01593 
01594             $oVoucher = oxNew( 'oxvoucher' );
01595 
01596             if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01597                 $oVoucher->getVoucherByNr( $sVoucherId, $this->_aVouchers, true );
01598                 $oVoucher->checkVoucherAvailability( $this->_aVouchers, $dPrice );
01599                 $oVoucher->checkUserAvailability( $this->getBasketUser() );
01600                 $oVoucher->markAsReserved();
01601             } else {
01602                 $oVoucher->load( $sVoucherId );
01603             }
01604 
01605             // saving voucher info
01606             $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
01607         } catch ( oxVoucherException $oEx ) {
01608 
01609             // problems adding voucher
01610             oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, true );
01611         }
01612 
01613         $this->onUpdate();
01614     }
01615 
01623     public function removeVoucher( $sVoucherId )
01624     {
01625         // removing if it exists
01626         if ( isset( $this->_aVouchers[$sVoucherId] ) ) {
01627 
01628             $oVoucher = oxNew( 'oxvoucher' );
01629             $oVoucher->load( $sVoucherId );
01630 
01631             $oVoucher->unMarkAsReserved();
01632 
01633             // unsetting it if exists this voucher in DB or not
01634             unset( $this->_aVouchers[$sVoucherId] );
01635             $this->onUpdate();
01636         }
01637 
01638     }
01639 
01645     public function resetUserInfo()
01646     {
01647         $this->setPayment( null );
01648         $this->setShipping( null );
01649     }
01650 
01656     protected function formatDiscount()
01657     {
01658         // discount information
01659         // formating discount value
01660         $this->aDiscounts = $this->getDiscounts();
01661         if ( count($this->aDiscounts) > 0 ) {
01662             $oLang = oxRegistry::getLang();
01663             foreach ($this->aDiscounts as $oDiscount) {
01664                 $oDiscount->fDiscount = $oLang->formatCurrency( $oDiscount->dDiscount, $this->getBasketCurrency() );
01665             }
01666         }
01667     }
01668 
01669 
01675     protected function _canSaveBasket()
01676     {
01677         $blCanSave = !$this->getConfig()->getConfigParam( 'blPerfNoBasketSaving' );
01678         return $blCanSave;
01679     }
01680 
01686     public function load()
01687     {
01688         $oUser = $this->getBasketUser();
01689         if ( !$oUser ) {
01690             return;
01691         }
01692 
01693         $oBasket = $oUser->getBasket( 'savedbasket' );
01694 
01695         // restoring from saved history
01696         $aSavedItems = $oBasket->getItems();
01697         foreach ( $aSavedItems as $oItem ) {
01698             try {
01699                 $oSelList = $oItem->getSelList();
01700 
01701                 $this->addToBasket( $oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true );
01702             } catch( oxArticleException $oEx ) {
01703                 // caught and ignored
01704             }
01705         }
01706     }
01707 
01713     protected function _save()
01714     {
01715         if ( $this->_canSaveBasket() ) {
01716 
01717             if ( $oUser = $this->getBasketUser() ) {
01718                 //first delete all contents
01719                 //#2039
01720                 $oSavedBasket = $oUser->getBasket( 'savedbasket' );
01721                 $oSavedBasket->delete();
01722 
01723                 //then save
01724                 foreach ( $this->_aBasketContents as $oBasketItem ) {
01725                     // discount or bundled products will be added automatically if available
01726                     if ( !$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle() ) {
01727                        $oSavedBasket->addItemToBasket( $oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams() );
01728                     }
01729                 }
01730             }
01731         }
01732     }
01733 
01745     /*
01746     protected function _addItemToSavedBasket( $sProductId , $dAmount, $aSel, $blOverride = false, $aPersParam = null )
01747     {
01748         // updating basket history
01749         if ( $oUser = $this->getBasketUser() ) {
01750             $oUser->getBasket( 'savedbasket' )->addItemToBasket( $sProductId, $dAmount, $aSel, $blOverride, $aPersParam );
01751         }
01752     }*/
01753 
01761     protected function _deleteSavedBasket()
01762     {
01763         // deleting basket if session user available
01764         if ( $oUser = $this->getBasketUser() ) {
01765             $oUser->getBasket( 'savedbasket' )->delete();
01766         }
01767 
01768         // basket exclude
01769         if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' )) {
01770             $this->setBasketRootCatId(null);
01771         }
01772     }
01773 
01779     protected function _findDelivCountry()
01780     {
01781         $myConfig = $this->getConfig();
01782         $oUser    = $this->getBasketUser();
01783 
01784         $sDelivCountry = null;
01785 
01786         if ( !$oUser ) {
01787             // don't calculate if not logged in unless specified otherwise
01788             $aHomeCountry = $myConfig->getConfigParam( 'aHomeCountry' );
01789             if ( $myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) && is_array( $aHomeCountry ) ) {
01790                 $sDelivCountry = current( $aHomeCountry );
01791             }
01792         } else {
01793 
01794             // ok, logged in
01795             if ( $sCountryId = $myConfig->getGlobalParameter( 'delcountryid' ) ) {
01796                 $sDelivCountry = $sCountryId;
01797             } elseif ( $sAddressId = oxSession::getVar( 'deladrid' ) ) {
01798 
01799                 $oDelAdress = oxNew( 'oxaddress' );
01800                 if ( $oDelAdress->load( $sAddressId ) ) {
01801                     $sDelivCountry = $oDelAdress->oxaddress__oxcountryid->value;
01802                 }
01803             }
01804 
01805             // still not found ?
01806             if ( !$sDelivCountry ) {
01807                 $sDelivCountry = $oUser->oxuser__oxcountryid->value;
01808             }
01809         }
01810 
01811         return $sDelivCountry;
01812     }
01813 
01819     public function deleteBasket()
01820     {
01821         $this->_aBasketContents = array();
01822         $this->getSession()->delBasket();
01823 
01824         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01825             $this->getSession()->getBasketReservations()->discardReservations();
01826         }
01827 
01828         // merging basket history
01829         $this->_deleteSavedBasket();
01830     }
01831 
01839     public function setPayment( $sPaymentId = null )
01840     {
01841         $this->_sPaymentId = $sPaymentId;
01842     }
01843 
01849     public function getPaymentId()
01850     {
01851         if ( !$this->_sPaymentId ) {
01852              $this->_sPaymentId = oxSession::getVar( 'paymentid' );
01853         }
01854         return $this->_sPaymentId;
01855     }
01856 
01864     public function setShipping( $sShippingSetId = null )
01865     {
01866         $this->_sShippingSetId = $sShippingSetId;
01867         oxSession::setVar( 'sShipSet', $sShippingSetId );
01868     }
01869 
01877     public function setDeliveryPrice( $oShippingPrice = null )
01878     {
01879         $this->_oDeliveryPrice = $oShippingPrice;
01880     }
01881 
01887     public function getShippingId()
01888     {
01889         if ( !$this->_sShippingSetId ) {
01890              $this->_sShippingSetId = oxSession::getVar( 'sShipSet' );
01891         }
01892 
01893         $sActPaymentId = $this->getPaymentId();
01894         // setting default if none is set
01895         if ( !$this->_sShippingSetId && $sActPaymentId != 'oxempty' ) {
01896             $oUser = $this->getUser();
01897 
01898             // choosing first preferred delivery set
01899             list( , $sActShipSet ) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData( null, $oUser, $this );
01900             // in case nothing was found and no user set - choosing default
01901             $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ( $oUser ? null : 'oxidstandard' );
01902         } elseif ( !$this->isAdmin() && $sActPaymentId == 'oxempty' ) {
01903             // in case 'oxempty' is payment id - delivery set must be reset
01904             $this->_sShippingSetId = null;
01905         }
01906 
01907         return $this->_sShippingSetId;
01908     }
01909 
01915     public function getBasketArticles()
01916     {
01917         $aBasketArticles = array();
01918 
01919         foreach ( $this->_aBasketContents as $sItemKey => $oBasketItem ) {
01920             try {
01921                 $oProduct = $oBasketItem->getArticle( true );
01922 
01923                 if ( $this->getConfig()->getConfigParam( 'bl_perfLoadSelectLists' ) ) {
01924                     // marking chosen select list
01925                     $aSelList = $oBasketItem->getSelList();
01926                     if ( is_array( $aSelList ) && ( $aSelectlist = $oProduct->getSelectLists( $sItemKey ) ) ) {
01927                         reset( $aSelList );
01928                         while ( list( $conkey, $iSel ) = each( $aSelList ) ) {
01929                             $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01930                             $aSelectlist[$conkey][$iSel]->selected = 1;
01931                         }
01932                         $oProduct->setSelectlist( $aSelectlist );
01933                     }
01934                 }
01935             } catch ( oxNoArticleException $oEx ) {
01936                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01937                 $this->removeItem( $sItemKey );
01938                 $this->calculateBasket( true );
01939                 continue;
01940             } catch ( oxArticleInputException $oEx ) {
01941                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01942                 $this->removeItem( $sItemKey );
01943                 $this->calculateBasket( true );
01944                 continue;
01945             }
01946 
01947             $aBasketArticles[$sItemKey] = $oProduct;
01948         }
01949         return $aBasketArticles;
01950     }
01951 
01957     public function getDiscountProductsPrice()
01958     {
01959         return $this->_oDiscountProductsPriceList;
01960     }
01961 
01967     public function getProductsPrice()
01968     {
01969         if ( is_null($this->_oProductsPriceList) ) {
01970             $this->_oProductsPriceList = oxNew( 'oxPriceList' );
01971         }
01972 
01973         return $this->_oProductsPriceList;
01974     }
01975 
01981     public function getPrice()
01982     {
01983         if ( is_null($this->_oPrice) ) {
01984             $this->_oPrice = oxNew( 'oxprice' );
01985         }
01986 
01987         return $this->_oPrice;
01988     }
01989 
01996     public function getOrderId()
01997     {
01998         return $this->_sOrderId;
01999     }
02000 
02008     public function setOrderId( $sId )
02009     {
02010         $this->_sOrderId = $sId;
02011     }
02012 
02021     public function getCosts( $sId = null )
02022     {
02023         // if user want some specific cost - return it
02024         if ( $sId ) {
02025             return isset( $this->_aCosts[$sId] )?$this->_aCosts[$sId]:null;
02026         }
02027         return $this->_aCosts;
02028     }
02029 
02035     public function getVouchers()
02036     {
02037         return $this->_aVouchers;
02038     }
02039 
02045     public function getProductsCount()
02046     {
02047         return $this->_iProductsCnt;
02048     }
02049 
02055     public function getItemsCount()
02056     {
02057         return $this->_dItemsCnt;
02058     }
02059 
02065     public function getWeight()
02066     {
02067         return $this->_dWeight;
02068     }
02069 
02075     public function getContents()
02076     {
02077         return $this->_aBasketContents;
02078     }
02079 
02087     public function getProductVats( $blFormatCurrency = true)
02088     {
02089         if ( !$this->_oNotDiscountedProductsPriceList ) {
02090             return array();
02091         }
02092 
02093         $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo( $this->isCalculationModeNetto() );
02094 
02095         $oUtils = oxRegistry::getUtils();
02096         foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
02097             if ( !isset( $aVats[$sKey] ) ) {
02098                 $aVats[$sKey] = 0;
02099             }
02100             // add prices of the same discounts
02101             $aVats[$sKey] += $oUtils->fRound( $dVat, $this->_oCurrency );
02102         }
02103 
02104         if ( $blFormatCurrency ) {
02105             $oLang = oxRegistry::getLang();
02106             foreach ( $aVats as $sKey => $dVat ) {
02107                 $aVats[$sKey] = $oLang->formatCurrency( $dVat, $this->getBasketCurrency() );
02108             }
02109         }
02110 
02111         return $aVats;
02112     }
02113 
02119     public function getDiscountedNettoPrice()
02120     {
02121         if ( $this->_oNotDiscountedProductsPriceList ) {
02122             return $this->_dDiscountedProductNettoPrice + $this->_oNotDiscountedProductsPriceList->getNettoSum();
02123         }
02124         return false;
02125     }
02126 
02134     public function setCardMessage( $sMessage )
02135     {
02136         $this->_sCardMessage = $sMessage;
02137     }
02138 
02144     public function getCardMessage()
02145     {
02146         return $this->_sCardMessage;
02147     }
02148 
02156     public function setCardId( $sCardId )
02157     {
02158         $this->_sCardId = $sCardId;
02159     }
02160 
02166     public function getCardId()
02167     {
02168         return $this->_sCardId;
02169     }
02170 
02176     public function getCard()
02177     {
02178         $oCard = null;
02179         if ( $sCardId = $this->getCardId() ) {
02180             $oCard = oxNew( 'oxwrapping' );
02181             $oCard->load( $sCardId );
02182             $oCard->setWrappingVat( $this->getAdditionalServicesVatPercent() );
02183         }
02184         return $oCard;
02185     }
02186 
02192     public function getTotalDiscount()
02193     {
02194         return $this->_oTotalDiscount;
02195     }
02196 
02202     public function getDiscounts()
02203     {
02204         if ( $this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
02205             return null;
02206         }
02207 
02208         return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
02209     }
02210 
02216     public function getVoucherDiscount()
02217     {
02218         if ($this->getConfig()->getConfigParam( 'bl_showVouchers' )) {
02219             return $this->_oVoucherDiscount;
02220         }
02221         return null;
02222     }
02223 
02231     public function setBasketCurrency( $oCurrency )
02232     {
02233         $this->_oCurrency = $oCurrency;
02234     }
02235 
02241     public function getBasketCurrency()
02242     {
02243         if ( $this->_oCurrency === null ) {
02244             $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
02245         }
02246 
02247         return $this->_oCurrency;
02248     }
02249 
02257     public function setSkipVouchersChecking( $blSkipChecking = null )
02258     {
02259         $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
02260     }
02261 
02267     public function hasSkipedDiscount()
02268     {
02269         return $this->_blSkipDiscounts;
02270     }
02271 
02279     public function setSkipDiscounts( $blSkip )
02280     {
02281         $this->_blSkipDiscounts = $blSkip;
02282     }
02283 
02289     public function getProductsNetPrice()
02290     {
02291         return oxRegistry::getLang()->formatCurrency( $this->getNettoSum(), $this->getBasketCurrency() );
02292     }
02293 
02299     public function getFProductsPrice()
02300     {
02301         return oxRegistry::getLang()->formatCurrency( $this->getBruttoSum(), $this->getBasketCurrency() );
02302     }
02303 
02309     public function getDelCostVatPercent()
02310     {
02311         return $this->getCosts( 'oxdelivery' )->getVat();
02312     }
02313 
02319     public function getDelCostVat()
02320     {
02321         $dDelVAT = $this->getCosts( 'oxdelivery' )->getVatValue();
02322 
02323         // blShowVATForDelivery option will be used, only for displaying, but not calculation
02324         if ( $dDelVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForDelivery' )) {
02325             return oxRegistry::getLang()->formatCurrency( $dDelVAT, $this->getBasketCurrency() );
02326         }
02327         return false;
02328     }
02329 
02335     public function getDelCostNet()
02336     {
02337         $oConfig = $this->getConfig();
02338 
02339         // blShowVATForDelivery option will be used, only for displaying, but not calculation
02340         if ( $oConfig->getConfigParam( 'blShowVATForDelivery' ) && ( $this->getBasketUser() || $oConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02341             $dNetPrice = $this->getCosts( 'oxdelivery' )->getNettoPrice();
02342             if ( $dNetPrice > 0 ) {
02343                 return oxRegistry::getLang()->formatCurrency( $dNetPrice, $this->getBasketCurrency() );
02344             }
02345         }
02346         return false;
02347     }
02348 
02354     public function getPayCostVatPercent()
02355     {
02356         return $this->getCosts( 'oxpayment' )->getVat();
02357     }
02358 
02364     public function getPayCostVat()
02365     {
02366         $dPayVAT = $this->getCosts( 'oxpayment' )->getVatValue();
02367 
02368         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02369         if ( $dPayVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02370             return oxRegistry::getLang()->formatCurrency( $dPayVAT, $this->getBasketCurrency() );
02371         }
02372         return false;
02373     }
02374 
02380     public function getPayCostNet()
02381     {
02382         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02383         if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02384             $oPaymentCost = $this->getCosts( 'oxpayment' );
02385             if ( $oPaymentCost && $oPaymentCost->getNettoPrice() ) {
02386                 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxpayment' )->getNettoPrice(), $this->getBasketCurrency() );
02387             }
02388         }
02389         return false;
02390     }
02391 
02397     public function getPaymentCosts()
02398     {
02399         $oPaymentCost = $this->getCosts( 'oxpayment' );
02400         if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02401             return $oPaymentCost->getBruttoPrice();
02402         }
02403     }
02404 
02410     public function getFPaymentCosts()
02411     {
02412         $oPaymentCost = $this->getCosts( 'oxpayment' );
02413         if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02414             return oxRegistry::getLang()->formatCurrency( $oPaymentCost->getBruttoPrice(), $this->getBasketCurrency() );
02415         }
02416         return false;
02417     }
02418 
02424     public function getVoucherDiscValue()
02425     {
02426         if ( $this->getVoucherDiscount() ) {
02427             return $this->getVoucherDiscount()->getBruttoPrice();
02428         }
02429         return false;
02430     }
02431 
02437     public function getFVoucherDiscountValue()
02438     {
02439         if ( $oVoucherDiscount = $this->getVoucherDiscount() ) {
02440             if ( $oVoucherDiscount->getBruttoPrice() ) {
02441                 return oxRegistry::getLang()->formatCurrency( $oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency() );
02442             }
02443         }
02444         return false;
02445     }
02446 
02447 
02453     public function getWrappCostVatPercent()
02454     {
02455         return $this->getCosts( 'oxwrapping' )->getVat();
02456     }
02457 
02458 
02464     public function getGiftCardCostVatPercent()
02465     {
02466         return $this->getCosts( 'oxgiftcard' )->getVat();
02467     }
02468 
02474     public function getWrappCostVat()
02475     {
02476         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02477         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02478             $oPrice = $this->getCosts( 'oxwrapping' );
02479 
02480             if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02481                 return oxRegistry::getLang()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02482             }
02483         }
02484 
02485         return false;
02486     }
02487 
02493     public function getWrappCostNet()
02494     {
02495         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02496         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02497             $oPrice = $this->getCosts( 'oxwrapping' );
02498 
02499              if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02500                  return  oxRegistry::getLang()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02501              }
02502         }
02503 
02504         return false;
02505     }
02506 
02512     public function getFWrappingCosts()
02513     {
02514         $oPrice = $this->getCosts( 'oxwrapping' );
02515 
02516         if ( $oPrice && $oPrice->getBruttoPrice() ) {
02517             return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02518         }
02519 
02520         return false;
02521     }
02522 
02523 
02529     public function getGiftCardCostVat()
02530     {
02531         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02532         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02533             $oPrice = $this->getCosts( 'oxgiftcard' );
02534 
02535             if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02536                 return oxLang::getInstance()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02537             }
02538         }
02539 
02540         return false;
02541 
02542     }
02543 
02549     public function getGiftCardCostNet()
02550     {
02551         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02552         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02553             $oPrice = $this->getCosts( 'oxgiftcard' );
02554 
02555             if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02556                 return  oxLang::getInstance()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02557             }
02558         }
02559 
02560         return false;
02561     }
02562 
02568     public function getFGiftCardCosts()
02569     {
02570         $oPrice = $this->getCosts( 'oxgiftcard' );
02571 
02572         if ( $oPrice && $oPrice->getBruttoPrice() ) {
02573             return oxLang::getInstance()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02574         }
02575         return false;
02576     }
02577 
02583     public function getFPrice()
02584     {
02585         return oxRegistry::getLang()->formatCurrency( $this->getPrice()->getBruttoPrice(), $this->getBasketCurrency() );
02586     }
02587 
02593     public function getFDeliveryCosts()
02594     {
02595         $oPrice = $this->getCosts( 'oxdelivery' );
02596 
02597         if ( $oPrice && ( $this->getBasketUser() || $this->getConfig()->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02598             return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02599         }
02600         return false;
02601     }
02602 
02608     public function getDeliveryCosts()
02609     {
02610         if ( $oDeliveryCost = $this->getCosts( 'oxdelivery' ) ) {
02611             return $oDeliveryCost->getBruttoPrice();
02612         }
02613         return false;
02614     }
02615 
02623     public function setTotalDiscount( $dDiscount )
02624     {
02625         $this->_oTotalDiscount = oxNew( 'oxPrice' );
02626         $this->_oTotalDiscount->setBruttoPriceMode();
02627         $this->_oTotalDiscount->add( $dDiscount );
02628     }
02629 
02636     public function getPriceForPayment()
02637     {
02638         $dPrice = $this->getDiscountedProductsBruttoPrice();
02639         //#1905 not discounted products should be included in payment amount calculation
02640         if ( $oPriceList = $this->getNotDiscountProductsPrice() ) {
02641             $dPrice += $oPriceList->getBruttoSum();
02642         }
02643 
02644         // adding delivery price to final price
02645         if ( $oDeliveryPrice = $this->_aCosts['oxdelivery'] ) {
02646             $dPrice += $oDeliveryPrice->getBruttoPrice();
02647         }
02648 
02649         return $dPrice;
02650     }
02651 
02652 
02658     public function _getDiscountedProductsSum()
02659     {
02660         if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02661             $dPrice = $oProductsPrice->getSum( $this->isCalculationModeNetto() );
02662         }
02663 
02664         // substracting total discount
02665         if ( $oPrice = $this->getTotalDiscount() ) {
02666             $dPrice -= $oPrice->getPrice();
02667         }
02668 
02669         if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02670             $dPrice -= $oVoucherPrice->getPrice();
02671         }
02672 
02673         return $dPrice;
02674     }
02675 
02681     public function getDiscountedProductsBruttoPrice()
02682     {
02683         if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02684             $dPrice = $oProductsPrice->getBruttoSum();
02685         }
02686 
02687         // substracting total discount
02688         if ( $oPrice = $this->getTotalDiscount() ) {
02689             $dPrice -= $oPrice->getBruttoPrice();
02690         }
02691 
02692         if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02693             $dPrice -= $oVoucherPrice->getBruttoPrice();
02694         }
02695 
02696         return $dPrice;
02697     }
02698 
02704     public function isBelowMinOrderPrice()
02705     {
02706         $blIsBelowMinOrderPrice = false;
02707         $sConfValue = $this->getConfig()->getConfigParam( 'iMinOrderPrice' );
02708         if ( is_numeric($sConfValue) && $this->getProductsCount() ) {
02709             $dMinOrderPrice = oxPrice::getPriceInActCurrency( ( int ) $sConfValue );
02710             $dNotDiscountedProductPrice = 0;
02711             if ( $oPrice = $this->getNotDiscountProductsPrice() ) {
02712                 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02713             }
02714             $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02715         }
02716 
02717         return $blIsBelowMinOrderPrice;
02718 
02719     }
02720 
02729     public function getArtStockInBasket( $sArtId, $sExpiredArtId = null )
02730     {
02731         $dArtStock = 0;
02732         foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
02733             if ( $oOrderArticle && ( $sExpiredArtId == null || $sExpiredArtId != $sItemKey ) ) {
02734                 if ( $oOrderArticle->getArticle( true )->getId() == $sArtId ) {
02735                     $dArtStock += $oOrderArticle->getAmount();
02736                 }
02737             }
02738         }
02739 
02740         return $dArtStock;
02741     }
02742 
02750     public function canAddProductToBasket( $sProductId )
02751     {
02752         $blCanAdd = null;
02753 
02754         // if basket category is not set..
02755         if ( $this->_sBasketCategoryId === null ) {
02756             $oCat = null;
02757 
02758             // request category
02759             if ( $oView = $this->getConfig()->getActiveView() ) {
02760                 if ( $oCat = $oView->getActCategory() ) {
02761                     if ( !$this->_isProductInRootCategory( $sProductId, $oCat->oxcategories__oxrootid->value ) ) {
02762                         $oCat = null;
02763                     } else {
02764                         $blCanAdd = true;
02765                     }
02766                 }
02767             }
02768 
02769             // product main category
02770             if ( !$oCat ) {
02771                 $oProduct = oxNew( "oxarticle" );
02772                 if ( $oProduct->load( $sProductId ) ) {
02773                     $oCat = $oProduct->getCategory();
02774                 }
02775             }
02776 
02777             // root category id
02778             if ( $oCat ) {
02779                 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02780             }
02781         }
02782 
02783         // avoiding double check..
02784         if ( $blCanAdd === null ) {
02785             $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory( $sProductId, $this->getBasketRootCatId() ) : true;
02786         }
02787 
02788         return $blCanAdd;
02789     }
02790 
02799     protected function _isProductInRootCategory( $sProductId, $sRootCatId )
02800     {
02801         $sO2CTable = getViewName( 'oxobject2category' );
02802         $sCatTable = getViewName( 'oxcategories' );
02803 
02804         $oDb = oxDb::getDb();
02805         $sParentId  = $oDb->getOne( "select oxparentid from oxarticles where oxid = ".$oDb->quote( $sProductId ) );
02806         $sProductId = $sParentId ? $sParentId : $sProductId;
02807 
02808         $sQ = "select 1 from {$sO2CTable}
02809                  left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02810                  where {$sO2CTable}.oxobjectid = ".$oDb->quote( $sProductId )." and
02811                        {$sCatTable}.oxrootid = ".$oDb->quote( $sRootCatId );
02812 
02813         return (bool) $oDb->getOne( $sQ );
02814     }
02815 
02823     public function setBasketRootCatId($sRoot)
02824     {
02825         $this->_sBasketCategoryId = $sRoot;
02826     }
02827 
02833     public function getBasketRootCatId()
02834     {
02835         return $this->_sBasketCategoryId;
02836     }
02837 
02845     public function setCatChangeWarningState( $blShow )
02846     {
02847         $this->_blShowCatChangeWarning = $blShow;
02848     }
02849 
02855     public function showCatChangeWarning()
02856     {
02857         return $this->_blShowCatChangeWarning;
02858     }
02859 
02867     public function setTsProductId( $sProductId )
02868     {
02869         $this->_sTsProductId = $sProductId;
02870     }
02871 
02877     public function getTsProductId()
02878     {
02879         return $this->_sTsProductId;
02880     }
02881 
02887     public function getFTsProtectionCosts()
02888     {
02889         $oProtectionCost = $this->getCosts( 'oxtsprotection' );
02890         if ( $oProtectionCost && $oProtectionCost->getBruttoPrice() ) {
02891             return oxRegistry::getLang()->formatCurrency( $oProtectionCost->getBruttoPrice(), $this->getBasketCurrency() );
02892         }
02893         return false;
02894     }
02895 
02901     public function getTsProtectionVatPercent()
02902     {
02903         return $this->getCosts( 'oxtsprotection' )->getVat();
02904     }
02905 
02911     public function getTsProtectionVat()
02912     {
02913         $dProtectionVAT = $this->getCosts( 'oxtsprotection' )->getVatValue();
02914         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02915         if ( $dProtectionVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02916             return oxRegistry::getLang()->formatCurrency( $dProtectionVAT, $this->getBasketCurrency() );
02917         }
02918         return false;
02919     }
02920 
02926     public function getTsProtectionNet()
02927     {
02928         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02929         if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02930             return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxtsprotection' )->getNettoPrice(), $this->getBasketCurrency() );
02931         }
02932         return false;
02933     }
02934 
02940     public function getTsProtectionCosts()
02941     {
02942         $oProtection = $this->getCosts( 'oxtsprotection' );
02943         if ( $oProtection ) {
02944             return $oProtection->getBruttoPrice();
02945         }
02946         return false;
02947     }
02948 
02954     public function getNotDiscountProductsPrice()
02955     {
02956         return $this->_oNotDiscountedProductsPriceList;
02957     }
02958 
02972     protected function _addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId )
02973     {
02974         if ( !$blOverride ) {
02975             $this->_blNewITemAdded = null;
02976             oxSession::setVar( "blAddedNewItem", true );
02977         }
02978     }
02979 
02985     public function __wakeUp()
02986     {
02987         $this->_blNewITemAdded = null;
02988         $this->_isCalculationModeNetto = null;
02989     }
02990 
02996     public function isNewItemAdded()
02997     {
02998         if ( $this->_blNewITemAdded == null ) {
02999             $this->_blNewITemAdded = (bool) oxSession::getVar( "blAddedNewItem" );
03000             oxSession::deleteVar( "blAddedNewItem" );
03001         }
03002         return $this->_blNewITemAdded;
03003     }
03004 
03010     public function hasDownloadableProducts()
03011     {
03012         $this->_blDownloadableProducts = false;
03013         foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
03014             if ( $oOrderArticle->getArticle( false ) && $oOrderArticle->getArticle( false )->isDownloadable() ) {
03015                 $this->_blDownloadableProducts = true;
03016                 break;
03017             }
03018         }
03019 
03020         return $this->_blDownloadableProducts;
03021     }
03022 
03023 }