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         // initialling 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         if (!$blBundle) {
00465             $this->_addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId );
00466         }
00467 
00468         // returning basket item object
00469         return $this->_aBasketContents[$sItemId];
00470     }
00471 
00479     public function addOrderArticleToBasket( $oOrderArticle )
00480     {
00481         // adding only if amount > 0
00482         if ( $oOrderArticle->oxorderarticles__oxamount->value > 0 && !$oOrderArticle->isBundle() ) {
00483 
00484             $this->_isForOrderRecalculation = true;
00485             $sItemId = $oOrderArticle->getId();
00486 
00487             //inserting new
00488             $this->_aBasketContents[$sItemId] = oxNew( 'oxbasketitem' );
00489             $this->_aBasketContents[$sItemId]->initFromOrderArticle( $oOrderArticle );
00490             $this->_aBasketContents[$sItemId]->setWrapping( $oOrderArticle->oxorderarticles__oxwrapid->value );
00491             $this->_aBasketContents[$sItemId]->setBundle( $oOrderArticle->isBundle() );
00492 
00493             //calling update method
00494             $this->onUpdate();
00495 
00496             return $this->_aBasketContents[$sItemId];
00497         } elseif ( $oOrderArticle->isBundle() ) {
00498             // deleting bundles, they are handled automatically
00499             $oOrderArticle->delete();
00500         }
00501     }
00502 
00510     public function setStockCheckMode( $blCheck )
00511     {
00512         $this->_blCheckStock = $blCheck;
00513     }
00514 
00520     public function getStockCheckMode()
00521     {
00522         return $this->_blCheckStock;
00523     }
00524 
00537     public function getItemKey( $sProductId, $aSel = null, $aPersParam = null, $blBundle = false, $sAdditionalParam = '' )
00538     {
00539         $aSel = ( $aSel != null) ? $aSel : array (0=>'0');
00540 
00541         $sItemKey = md5( $sProductId.'|'.serialize( $aSel ).'|'.serialize( $aPersParam ).'|'.( int ) $blBundle . '|' . serialize( $sAdditionalParam ) );
00542 
00543         return $sItemKey;
00544     }
00545 
00546 
00554     public function removeItem( $sItemKey )
00555     {
00556         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
00557             if (isset($this->_aBasketContents[$sItemKey])) {
00558                 $sArticleId = $this->_aBasketContents[$sItemKey]->getProductId();
00559                 if ($sArticleId) {
00560                     $this->getSession()
00561                             ->getBasketReservations()
00562                             ->discardArticleReservation($sArticleId);
00563                 }
00564             }
00565         }
00566         unset( $this->_aBasketContents[$sItemKey] );
00567 
00568         // basket exclude
00569         if ( !count($this->_aBasketContents) && $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' ) ) {
00570             $this->setBasketRootCatId(null);
00571         }
00572     }
00573 
00579     protected function _clearBundles()
00580     {
00581         reset( $this->_aBasketContents );
00582         while ( list( $sItemKey, $oBasketItem ) = each( $this->_aBasketContents ) ) {
00583             if ( $oBasketItem->isBundle() ) {
00584                 $this->removeItem( $sItemKey );
00585             }
00586         }
00587     }
00588 
00596     protected function _getArticleBundles( $oBasketItem )
00597     {
00598         $aBundles = array();
00599 
00600         if ( $oBasketItem->isBundle() ) {
00601             return $aBundles;
00602         }
00603 
00604         $oArticle = $oBasketItem->getArticle( true );
00605         if ( $oArticle && $oArticle->oxarticles__oxbundleid->value ) {
00606             $aBundles[$oArticle->oxarticles__oxbundleid->value] = 1;
00607         }
00608 
00609         return $aBundles;
00610     }
00611 
00620     protected function _getItemBundles( $oBasketItem, $aBundles = array() )
00621     {
00622         if ( $oBasketItem->isBundle() ) {
00623             return array();
00624         }
00625 
00626         // does this object still exists ?
00627         if ( $oArticle = $oBasketItem->getArticle() ) {
00628             $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketItemBundleDiscounts( $oArticle, $this, $this->getBasketUser() );
00629 
00630             foreach ( $aDiscounts as $oDiscount ) {
00631 
00632                 $iAmnt = $oDiscount->getBundleAmount( $oBasketItem->getAmount() );
00633                 if ( $iAmnt ) {
00634                     //init array element
00635                     if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00636                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00637                     }
00638 
00639                     if ($oDiscount->oxdiscount__oxitmmultiple->value) {
00640                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $iAmnt;
00641                     } else {
00642                         $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = $iAmnt;
00643                     }
00644                 }
00645             }
00646         }
00647 
00648         return $aBundles;
00649     }
00650 
00658     protected function _getBasketBundles( $aBundles = array() )
00659     {
00660         $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketBundleDiscounts( $this, $this->getBasketUser() );
00661 
00662         // calculating amount of non bundled/discount items
00663         $dAmount = 0;
00664         foreach ( $this->_aBasketContents as $oBasketItem ) {
00665             if ( !( $oBasketItem->isBundle() || $oBasketItem->isDiscountArticle() ) ) {
00666                 $dAmount += $oBasketItem->getAmount();
00667             }
00668         }
00669 
00670         foreach ( $aDiscounts as $oDiscount ) {
00671             if ($oDiscount->oxdiscount__oxitmartid->value) {
00672                 if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00673                     $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00674                 }
00675 
00676                 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $oDiscount->getBundleAmount( $dAmount );
00677             }
00678         }
00679 
00680         return $aBundles;
00681     }
00682 
00689     protected function _addBundles()
00690     {
00691         $aBundles = array();
00692         // iterating through articles and binding bundles
00693         foreach ( $this->_aBasketContents as $key => $oBasketItem ) {
00694             try {
00695                 // adding discount type bundles
00696                 if ( !$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle() ) {
00697                     $aBundles = $this->_getItemBundles( $oBasketItem, $aBundles );
00698                 } else {
00699                     continue;
00700                 }
00701 
00702                     // adding item type bundles
00703                     $aArtBundles = $this->_getArticleBundles( $oBasketItem );
00704 
00705                     // adding bundles to basket
00706                     $this->_addBundlesToBasket( $aArtBundles );
00707             } catch ( oxNoArticleException $oEx ) {
00708                 $this->removeItem( $key );
00709                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00710             } catch( oxArticleInputException $oEx ) {
00711                 $this->removeItem( $key );
00712                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00713             }
00714         }
00715 
00716         // adding global basket bundles
00717         $aBundles = $this->_getBasketBundles( $aBundles );
00718 
00719         // adding all bundles to basket
00720         if ( $aBundles ) {
00721             $this->_addBundlesToBasket( $aBundles );
00722         }
00723     }
00724 
00732     protected function _addBundlesToBasket( $aBundles )
00733     {
00734         foreach ( $aBundles as $sBundleId => $dAmount ) {
00735             if ( $dAmount ) {
00736                 try {
00737                     if ( $oBundleItem = $this->addToBasket( $sBundleId, $dAmount, null, null, false, true ) ) {
00738                         $oBundleItem->setAsDiscountArticle( true );
00739                     }
00740                 } catch(oxArticleException $oEx) {
00741                     // caught and ignored
00742                 }
00743             }
00744         }
00745 
00746     }
00747 
00753     protected function _calcItemsPrice()
00754     {
00755         // resetting
00756         $this->setSkipDiscounts( false );
00757         $this->_iProductsCnt = 0; // count different types
00758         $this->_dItemsCnt    = 0; // count of item units
00759         $this->_dWeight      = 0; // basket weight
00760 
00761         $this->_oProductsPriceList = oxNew( 'oxpricelist' );
00762         $this->_oDiscountProductsPriceList = oxNew( 'oxpricelist' );
00763         $this->_oNotDiscountedProductsPriceList = oxNew( 'oxpricelist' );
00764 
00765         $oDiscountList = oxRegistry::get("oxDiscountList");
00766 
00767         foreach ( $this->_aBasketContents as $oBasketItem ) {
00768             $this->_iProductsCnt++;
00769             $this->_dItemsCnt += $oBasketItem->getAmount();
00770             $this->_dWeight   += $oBasketItem->getWeight();
00771 
00772             if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle( true ) ) ) {
00773 
00774                 $oBasketPrice = $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $this );
00775                 $oBasketItem->setRegularUnitPrice( clone $oBasketPrice );
00776 
00777                 if ( !$oArticle->skipDiscounts() && $this->canCalcDiscounts() ) {
00778                     // apply basket type discounts for item
00779                     $aDiscounts = $oDiscountList->getBasketItemDiscounts( $oArticle, $this, $this->getBasketUser() );
00780                     reset( $aDiscounts );
00781                     foreach ( $aDiscounts as $oDiscount ) {
00782                         $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
00783                     }
00784                     $oBasketPrice->calculateDiscount();
00785                 } else {
00786                     $oBasketItem->setSkipDiscounts( true );
00787                     $this->setSkipDiscounts( true );
00788                 }
00789 
00790                 $oBasketItem->setPrice( $oBasketPrice );
00791                 $this->_oProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00792 
00793                 //P collect discount values for basket items which are discountable
00794                 if ( !$oArticle->skipDiscounts() ) {
00795 
00796                     $this->_oDiscountProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00797                 } else {
00798                     $this->_oNotDiscountedProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00799                     $oBasketItem->setSkipDiscounts( true );
00800                     $this->setSkipDiscounts( true );
00801                 }
00802             } elseif ( $oBasketItem->isBundle() ) {
00803                 // if bundles price is set to zero
00804                 $oPrice = oxNew( "oxprice");
00805                 $oBasketItem->setPrice( $oPrice );
00806             }
00807         }
00808     }
00809 
00817     public function setDiscountCalcMode( $blCalcDiscounts )
00818     {
00819         $this->_blCalcDiscounts = $blCalcDiscounts;
00820     }
00821 
00827     public function canCalcDiscounts()
00828     {
00829         return $this->_blCalcDiscounts;
00830     }
00831 
00841     protected function _mergeDiscounts( $aDiscounts, $aItemDiscounts)
00842     {
00843         foreach ( $aItemDiscounts as $sKey => $oDiscount ) {
00844             // add prices of the same discounts
00845             if ( array_key_exists ($sKey, $aDiscounts) ) {
00846                 $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
00847             } else {
00848                 $aDiscounts[$sKey] = $oDiscount;
00849             }
00850         }
00851         return $aDiscounts;
00852     }
00853 
00859     protected function _calcDeliveryCost()
00860     {
00861         if ( $this->_oDeliveryPrice !== null ) {
00862             return $this->_oDeliveryPrice;
00863         }
00864         $myConfig  = $this->getConfig();
00865         $oDeliveryPrice = oxNew( 'oxprice' );
00866 
00867         if ( $this->getConfig()->getConfigParam( 'blDeliveryVatOnTop' ) ) {
00868             $oDeliveryPrice->setNettoPriceMode();
00869         } else {
00870             $oDeliveryPrice->setBruttoPriceMode();
00871         }
00872 
00873         // don't calculate if not logged in
00874         $oUser = $this->getBasketUser();
00875 
00876         if ( !$oUser && !$myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) {
00877             return $oDeliveryPrice;
00878         }
00879 
00880         // VAT for delivery will be calculated always (#3757)
00881         // blCalcVATForDelivery option is @deprecated since 2012-03-23 in version 4.6
00882         // the option blShowVATForDelivery will be used only for displaying
00883         $fDelVATPercent = 0;
00884         $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00885         $oDeliveryPrice->setVat( $fDelVATPercent );
00886 
00887         // list of active delivery costs
00888         if ( $myConfig->getConfigParam('bl_perfLoadDelivery') ) {
00889             $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList( $this,
00890                                         $oUser,
00891                                         $this->_findDelivCountry(),
00892                                         $this->getShippingId()
00893                                     );
00894 
00895             if ( count( $aDeliveryList ) > 0 ) {
00896                 foreach ( $aDeliveryList as $oDelivery ) {
00897                     //debug trace
00898                     if ( $myConfig->getConfigParam( 'iDebug' ) == 5 ) {
00899                         echo( "DelCost : ".$oDelivery->oxdelivery__oxtitle->value."<br>" );
00900                     }
00901                     $oDeliveryPrice->addPrice( $oDelivery->getDeliveryPrice( $fDelVATPercent ) );
00902                 }
00903             }
00904         }
00905 
00906         return $oDeliveryPrice;
00907     }
00908 
00914     public function getBasketUser()
00915     {
00916         if ( $this->_oUser == null ) {
00917             return $this->getUser();
00918         }
00919 
00920         return $this->_oUser;
00921     }
00922 
00930     public function setBasketUser( $oUser )
00931     {
00932         $this->_oUser = $oUser;
00933     }
00934 
00935     //P
00941     public function getMostUsedVatPercent()
00942     {
00943         if ( $this->_oProductsPriceList ) {
00944             return $this->_oProductsPriceList->getMostUsedVatPercent();
00945         }
00946     }
00947 
00953     public function getAdditionalServicesVatPercent()
00954     {
00955         if ( $this->_oProductsPriceList ) {
00956             if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional') {
00957                 return $this->_oProductsPriceList->getProportionalVatPercent();
00958             } else {
00959                 return $this->_oProductsPriceList->getMostUsedVatPercent();
00960             }
00961         }
00962     }
00963 
00969     public function isProportionalCalculationOn()
00970     {
00971         if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional' ) {
00972             return true;
00973         }
00974         return false;
00975     }
00976 
00977 
00978  //P
00985     protected function _calcTotalPrice()
00986     {
00987         // 1. add products price
00988         $dprice = $this->_dBruttoSum;//$this->_oProductsPriceList->getBruttoSum();
00989         $this->_oPrice = oxNew( 'oxPrice' );
00990         $this->_oPrice->setBruttoPriceMode();
00991         $this->_oPrice->setPrice( $dprice );
00992 
00993         // 2. substract discounts
00994         if ( $dprice && !$this->isCalculationModeNetto() ) {
00995 
00996             // 2.1 applying basket item discounts
00997             /*foreach ( $this->_aItemDiscounts as $oDiscount ) {
00998 
00999                 // skipping bundle discounts
01000                 if ( $oDiscount->sType == 'itm' ) {
01001                     continue;
01002                 }
01003                 $this->_oPrice->subtract( $oDiscount->dDiscount );
01004             }*/
01005 
01006             // 2.2 applying basket discounts
01007             $this->_oPrice->subtract( $this->_oTotalDiscount->getBruttoPrice() );
01008 
01009             // 2.3 applying voucher discounts
01010             if ($oVoucherDisc = $this->getVoucherDiscount()) {
01011                 $this->_oPrice->subtract( $oVoucherDisc->getBruttoPrice() );
01012             }
01013         }
01014 
01015         // 2.3 add delivery cost
01016         if ( isset( $this->_aCosts['oxdelivery'] ) ) {
01017             $this->_oPrice->add( $this->_aCosts['oxdelivery']->getBruttoPrice() );
01018         }
01019 
01020         // 2.4 add wrapping price
01021         if ( isset( $this->_aCosts['oxwrapping'] ) ) {
01022             $this->_oPrice->add( $this->_aCosts['oxwrapping']->getBruttoPrice() );
01023         }
01024         if ( isset( $this->_aCosts['oxgiftcard'] ) ) {
01025             $this->_oPrice->add( $this->_aCosts['oxgiftcard']->getBruttoPrice() );
01026         }
01027 
01028         // 2.5 add payment price
01029         if ( isset( $this->_aCosts['oxpayment'] ) ) {
01030             $this->_oPrice->add( $this->_aCosts['oxpayment']->getBruttoPrice() );
01031         }
01032 
01033         // 2.6 add TS protection price
01034         if ( isset( $this->_aCosts['oxtsprotection'] ) ) {
01035             $this->_oPrice->add( $this->_aCosts['oxtsprotection']->getBruttoPrice() );
01036         }
01037 
01038     }
01039 
01047     public function setVoucherDiscount( $dDiscount )
01048     {
01049         $this->_oVoucherDiscount = oxNew( 'oxPrice' );
01050         $this->_oVoucherDiscount->setBruttoPriceMode();
01051         $this->_oVoucherDiscount->add( $dDiscount );
01052     }
01053 
01059     protected function _calcVoucherDiscount()
01060     {
01061         if ( $this->getConfig()->getConfigParam( 'bl_showVouchers' ) && ($this->_oVoucherDiscount === null || ( $this->_blUpdateNeeded && !$this->isAdmin() ) ) ) {
01062 
01063             $this->_oVoucherDiscount = $this->_getPriceObject();
01064 
01065             // calculating price to apply discount
01066             $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() ) - $this->_oTotalDiscount->getPrice();
01067 
01068             // recalculating
01069             if ( count( $this->_aVouchers ) ) {
01070                 $oLang = oxRegistry::getLang();
01071                 foreach ( $this->_aVouchers as $sVoucherId => $oStdVoucher ) {
01072                     $oVoucher = oxNew( 'oxvoucher' );
01073                     try { // checking
01074                         $oVoucher->load( $oStdVoucher->sVoucherId );
01075 
01076                         if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01077                             $oVoucher->checkBasketVoucherAvailability( $this->_aVouchers, $dPrice );
01078                             $oVoucher->checkUserAvailability( $this->getBasketUser() );
01079                         }
01080 
01081                         // assigning real voucher discount value as this is the only place where real value is calculated
01082                         $dVoucherdiscount = $oVoucher->getDiscountValue( $dPrice );
01083 
01084                         if ( $dVoucherdiscount > 0 ) {
01085 
01086                             if ( $oVoucher->getDiscountType() == 'absolute' ) {
01087                                 $dVatPart = ( $dPrice - $dVoucherdiscount ) / $dPrice * 100;
01088                             } else {
01089                                 $dVatPart = 100 - $oVoucher->getDiscount();
01090                             }
01091 
01092                             if ( !$this->_aDiscountedVats ) {
01093                                 if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01094                                     $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01095                                 }
01096                             }
01097 
01098                             // apply discount to vat
01099                             foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01100                                 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01101                             }
01102                         }
01103 
01104                         // accumulating discount value
01105                         $this->_oVoucherDiscount->add( $dVoucherdiscount );
01106 
01107                         // collecting formatted for preview
01108                         $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency( $dVoucherdiscount, $this->getBasketCurrency() );
01109                         $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01110 
01111                         // subtracting voucher discount
01112                         $dPrice = $dPrice - $dVoucherdiscount;
01113 
01114 
01115 
01116                     } catch ( oxVoucherException $oEx ) {
01117 
01118                         // removing voucher on error
01119                         $oVoucher->unMarkAsReserved();
01120                         unset( $this->_aVouchers[$sVoucherId] );
01121 
01122                         // storing voucher error info
01123                         oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01124                     }
01125                 }
01126             }
01127         }
01128     }
01129 
01136     protected function _applyDiscounts()
01137     {
01138         $dBruttoPrice = 0;
01139 
01140         //apply discounts for brutto price
01141         $dDiscountedBruttoPrice = $this->_getDiscountedProductsSum();
01142         $oTotalDiscount   = $this->getTotalDiscount();
01143         $oVoucherDiscount = $this->getVoucherDiscount();
01144 
01145         $oUtils = oxRegistry::getUtils();
01146         $dVatSum = 0;
01147         foreach ( $this->_aDiscountedVats as $dVat ) {
01148             $dVatSum +=  $oUtils->fRound( $dVat, $this->_oCurrency);
01149         }
01150 
01151         $oNotDiscounted = $this->getNotDiscountProductsPrice();
01152 
01153         if ( $this->isCalculationModeNetto() ) {
01154             // netto view mode
01155             $this->setNettoSum($this->getProductsPrice()->getSum());
01156             $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedBruttoPrice + $dVatSum);
01157         } else {
01158             // brutto view mode
01159             $this->setNettoSum( $oNotDiscounted->getSum() + $dDiscountedBruttoPrice - $dVatSum );
01160             $this->setBruttoSum( $this->getProductsPrice()->getSum(false) );
01161         }
01162     }
01168     public function isPriceViewModeNetto()
01169     {
01170         $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
01171         $oUser = $this->getBasketUser();
01172         if ( $oUser ) {
01173             $blResult = $oUser->isPriceViewModeNetto();
01174         }
01175 
01176         return $blResult;
01177     }
01178 
01184     protected function _getPriceObject()
01185     {
01186         $oPrice = oxNew( 'oxPrice' );
01187 
01188         if ( $this->isCalculationModeNetto() ) {
01189             $oPrice->setNettoPriceMode();
01190         } else {
01191             $oPrice->setBruttoPriceMode();
01192         }
01193 
01194         return $oPrice;
01195     }
01196 
01202     protected function _calcBasketDiscount()
01203     {
01204         // resetting
01205         $this->_aDiscounts = array();
01206 
01207         // P using prices sum which has discount, not sum of skipped discounts
01208         $dOldprice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01209 
01210         // add basket discounts
01211         if ( $this->_oTotalDiscount !== null  && isset($this->_isForOrderRecalculation) && $this->_isForOrderRecalculation ) {
01212             //if total discutn was setted on order recalculation
01213             $oTotalPrice = $this->getTotalDiscount();
01214             $oDiscount = oxNew('oxDiscount');
01215             $oDiscount->oxdiscount__oxaddsum = new oxField( $oTotalPrice->getPrice() );
01216             $oDiscount->oxdiscount__oxaddsumtype = new oxField( 'abs' );
01217             $aDiscounts[] = $oDiscount;
01218         } else {
01219             // discounts for basket
01220             $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts( $this, $this->getBasketUser() );
01221         }
01222 
01223         if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01224                 $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01225         }
01226 
01227         foreach ( $aDiscounts as $oDiscount ) {
01228 
01229             // storing applied discounts
01230             $oStdDiscount = $oDiscount->getSimpleDiscount();
01231 
01232             // skipping bundle discounts
01233             if ( $oDiscount->oxdiscount__oxaddsumtype->value == 'itm' ) {
01234                 continue;
01235             }
01236 
01237             // saving discount info
01238             $oStdDiscount->dDiscount = $oDiscount->getAbsValue( $dOldprice );
01239 
01240             //var_dump($oDiscount->getPercentage( $dOldprice ));
01241 
01242             $dVatPart = 100 - $oDiscount->getPercentage( $dOldprice );
01243 
01244             // if discount is more than basket sum
01245             if ( $dOldprice < $oStdDiscount->dDiscount ) {
01246                 $oStdDiscount->dDiscount = $dOldprice;
01247                 $dVatPart = 0;
01248             }
01249 
01250             // apply discount to vat
01251             foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01252                 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01253             }
01254 
01255             //storing discount
01256             if ($oStdDiscount->dDiscount != 0) {
01257                 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01258                 // subtracting product price after discount
01259                 $dOldprice = $dOldprice - $oStdDiscount->dDiscount;
01260             }
01261         }
01262     }
01263 
01269     protected function _calcBasketTotalDiscount()
01270     {
01271         if ( $this->_oTotalDiscount === null || ( !$this->isAdmin() ) ) {
01272 
01273             $this->_oTotalDiscount = $this->_getPriceObject();
01274 
01275             if ( is_array($this->_aDiscounts) ) {
01276                 foreach ( $this->_aDiscounts as $oDiscount ) {
01277 
01278                     // skipping bundle discounts
01279                     if ( $oDiscount->sType == 'itm' ) {
01280                         continue;
01281                     }
01282 
01283                     // add discount value to total basket discount
01284                     $this->_oTotalDiscount->add( $oDiscount->dDiscount );
01285                 }
01286             }
01287         }
01288     }
01289 
01298     protected function _calcBasketWrapping()
01299     {
01300         $oWrappingPrices = oxNew( 'oxPriceList' );
01301 
01302         foreach ( $this->_aBasketContents as $oBasketItem ) {
01303 
01304             if ( ( $oWrapping = $oBasketItem->getWrapping() ) ) {
01305 
01306                 $oWrappingPrice = $oWrapping->getWrappingPrice( $oBasketItem->getAmount() );
01307                 $oWrappingPrice->setVat( $oBasketItem->getPrice()->getVat() );
01308 
01309                 $oWrappingPrices->addToPriceList( $oWrappingPrice );
01310             }
01311         }
01312 
01313         if ( $oWrappingPrices->getCount() ) {
01314             $oWrappingCost = oxNew( 'oxPrice' );
01315             $oWrappingCost = $oWrappingPrices->calculateToPrice();
01316         }
01317 
01318         return $oWrappingCost;
01319     }
01320 
01329     protected function _calcBasketGiftCard()
01330     {
01331         $oGiftCardPrice = oxNew( 'oxPrice' );
01332 
01333         if ( $this->getConfig()->getConfigParam( 'blWrappingVatOnTop' ) ) {
01334             $oGiftCardPrice->setNettoPriceMode();
01335         } else {
01336             $oGiftCardPrice->setBruttoPriceMode();
01337         }
01338 
01339         $dVATPercent = $this->getAdditionalServicesVatPercent();
01340 
01341         $oGiftCardPrice->setVat( $dVATPercent );
01342 
01343         // gift card price calculation
01344         if ( ( $oCard = $this->getCard() ) ) {
01345             if ($dVATPercent !== null) {
01346                 $oCard->setWrappingVat($dVATPercent);
01347             }
01348             $oGiftCardPrice->addPrice( $oCard->getWrappingPrice() );
01349         }
01350 
01351         return $oGiftCardPrice;
01352     }
01353 
01360     protected function _calcPaymentCost()
01361     {
01362         // resetting values
01363         $oPaymentPrice = oxNew( 'oxPrice' );
01364 
01365         // payment
01366         if ( ( $this->_sPaymentId = $this->getPaymentId() ) ) {
01367 
01368             $oPayment = oxNew( 'oxpayment' );
01369             $oPayment->load( $this->_sPaymentId );
01370 
01371             $oPayment->calculate( $this );
01372             $oPaymentPrice = $oPayment->getPrice();
01373         }
01374 
01375         return $oPaymentPrice;
01376     }
01377 
01384     protected function _calcTsProtectionCost()
01385     {
01386         if ( ( $this->getTsProductId() ) ) {
01387             $oTsProtection = oxNew('oxtsprotection');
01388             $oTsProduct = $oTsProtection->getTsProduct( $this->getTsProductId() );
01389             $oProtectionPrice = $oTsProduct->getPrice();
01390             $oProtectionPrice->setVat( $this->getAdditionalServicesVatPercent() );
01391         } else {
01392             $oProtectionPrice = oxNew( 'oxPrice' );
01393         }
01394 
01395         return $oProtectionPrice;
01396     }
01397 
01406     public function setCost( $sCostName, $oPrice = null )
01407     {
01408         $this->_aCosts[$sCostName] = $oPrice;
01409     }
01410 
01419     public function calculateBasket( $blForceUpdate = false )
01420     {
01421         /*
01422         //would be good to perform the reset of previous calculation
01423         //at least you can use it for the debug
01424         $this->_aDiscounts = array();
01425         $this->_aItemDiscounts = array();
01426         $this->_oTotalDiscount = null;
01427         $this->_dDiscountedProductNettoPrice = 0;
01428         $this->_aDiscountedVats = array();
01429         $this->_oPrice = null;
01430         $this->_oNotDiscountedProductsPriceList = null;
01431         $this->_oProductsPriceList = null;
01432         $this->_oDiscountProductsPriceList = null;*/
01433 
01434         if ( !$this->isEnabled() ) {
01435             return;
01436         }
01437 
01438         if ( $blForceUpdate ) {
01439             $this->onUpdate();
01440         }
01441 
01442         if ( !($this->_blUpdateNeeded || $blForceUpdate) ) {
01443             return;
01444         }
01445 
01446         $this->_aCosts = array();
01447 
01448         //  1. saving basket to the database
01449         $this->_save();
01450 
01451         //  2. remove all bundles
01452         $this->_clearBundles();
01453 
01454         //  3. generate bundle items
01455         $this->_addBundles();
01456 
01457         // reserve active basket
01458         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01459             $this->getSession()->getBasketReservations()->reserveBasket($this);
01460         }
01461 
01462         //  4. calculating item prices
01463         $this->_calcItemsPrice();
01464 
01465         //  5. calculating/applying discounts
01466         $this->_calcBasketDiscount();
01467 
01468         //  6. calculating basket total discount
01469         $this->_calcBasketTotalDiscount();
01470 
01471         //  7. check for vouchers
01472         $this->_calcVoucherDiscount();
01473 
01474         //  8. applies all discounts to pricelist
01475         $this->_applyDiscounts();
01476 
01477         //  9. calculating additional costs:
01478         //  9.1: delivery
01479         $this->setCost( 'oxdelivery', $this->_calcDeliveryCost() );
01480 
01481         //  9.2: adding wrapping and gift card costs
01482         $this->setCost( 'oxwrapping', $this->_calcBasketWrapping() );
01483 
01484         $this->setCost( 'oxgiftcard', $this->_calcBasketGiftCard() );
01485 
01486         //  9.3: adding payment cost
01487         $this->setCost( 'oxpayment', $this->_calcPaymentCost() );
01488 
01489         //  9.4: adding TS protection cost
01490         $this->setCost( 'oxtsprotection', $this->_calcTsProtectionCost() );
01491 
01492         //  10. calculate total price
01493         $this->_calcTotalPrice();
01494 
01495         //  11. formatting discounts
01496         $this->formatDiscount();
01497 
01498         //  12.setting to up-to-date status
01499         $this->afterUpdate();
01500     }
01501 
01507     public function onUpdate()
01508     {
01509         $this->_blUpdateNeeded = true;
01510     }
01511 
01517     public function afterUpdate()
01518     {
01519         $this->_blUpdateNeeded = false;
01520     }
01521 
01529     public function getBasketSummary()
01530     {
01531         if ( $this->_blUpdateNeeded || $this->_aBasketSummary === null ) {
01532             $this->_aBasketSummary = new stdclass();
01533             $this->_aBasketSummary->aArticles = array();
01534             $this->_aBasketSummary->aCategories = array();
01535             $this->_aBasketSummary->iArticleCount = 0;
01536             $this->_aBasketSummary->dArticlePrice = 0;
01537             $this->_aBasketSummary->dArticleDiscountablePrice = 0;
01538         }
01539 
01540         if ( !$this->isEnabled() ) {
01541             return $this->_aBasketSummary;
01542         }
01543 
01544         $myConfig = $this->getConfig();
01545         foreach ( $this->_aBasketContents as $oBasketItem ) {
01546             if ( !$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false) ) {
01547                 $aCatIds = $oArticle->getCategoryIds();
01548                 //#M530 if price is not loaded for articles
01549                 $dPrice = 0;
01550                 $dDiscountablePrice = 0;
01551                 if ( ( $oPrice = $oArticle->getPrice( $oBasketItem->getAmount() ) ) ) {
01552                     $dPrice = $oPrice->getPrice();
01553                     if ( !$oArticle->skipDiscounts() ) {
01554                         $dDiscountablePrice = $dPrice;
01555                     }
01556                 }
01557 
01558                 foreach ( $aCatIds as $sCatId ) {
01559                     if ( !isset( $this->_aBasketSummary->aCategories[$sCatId] ) ) {
01560                         $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
01561                     }
01562 
01563                     $this->_aBasketSummary->aCategories[$sCatId]->dPrice  += $dPrice * $oBasketItem->getAmount();
01564                     $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01565                     $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
01566                     $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
01567                 }
01568 
01569                 // variant handling
01570                 if ( ($sParentId = $oArticle->getProductParentId()) && $myConfig->getConfigParam( 'blVariantParentBuyable' ) ) {
01571                     if ( !isset( $this->_aBasketSummary->aArticles[$sParentId] ) ) {
01572                         $this->_aBasketSummary->aArticles[$sParentId] = 0;
01573                     }
01574                     $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
01575                 }
01576 
01577                 if ( !isset( $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] ) ) {
01578                     $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
01579                 }
01580 
01581                 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
01582                 $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
01583                 $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
01584                 $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01585             }
01586         }
01587         return $this->_aBasketSummary;
01588     }
01589 
01601     public function addVoucher( $sVoucherId )
01602     {
01603         // calculating price to check
01604         // P using prices sum which has discount, not sum of skipped discounts
01605         $dPrice = 0;
01606         if ( $this->_oDiscountProductsPriceList ) {
01607             $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01608         }
01609 
01610         try { // trying to load voucher and apply it
01611 
01612             $oVoucher = oxNew( 'oxvoucher' );
01613 
01614             if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01615                 $oVoucher->getVoucherByNr( $sVoucherId, $this->_aVouchers, true );
01616                 $oVoucher->checkVoucherAvailability( $this->_aVouchers, $dPrice );
01617                 $oVoucher->checkUserAvailability( $this->getBasketUser() );
01618                 $oVoucher->markAsReserved();
01619             } else {
01620                 $oVoucher->load( $sVoucherId );
01621             }
01622 
01623             // saving voucher info
01624             $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
01625         } catch ( oxVoucherException $oEx ) {
01626 
01627             // problems adding voucher
01628             oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, true );
01629         }
01630 
01631         $this->onUpdate();
01632     }
01633 
01641     public function removeVoucher( $sVoucherId )
01642     {
01643         // removing if it exists
01644         if ( isset( $this->_aVouchers[$sVoucherId] ) ) {
01645 
01646             $oVoucher = oxNew( 'oxvoucher' );
01647             $oVoucher->load( $sVoucherId );
01648 
01649             $oVoucher->unMarkAsReserved();
01650 
01651             // unsetting it if exists this voucher in DB or not
01652             unset( $this->_aVouchers[$sVoucherId] );
01653             $this->onUpdate();
01654         }
01655 
01656     }
01657 
01663     public function resetUserInfo()
01664     {
01665         $this->setPayment( null );
01666         $this->setShipping( null );
01667     }
01668 
01674     protected function formatDiscount()
01675     {
01676         // discount information
01677         // formatting discount value
01678         $this->aDiscounts = $this->getDiscounts();
01679         if ( count($this->aDiscounts) > 0 ) {
01680             $oLang = oxRegistry::getLang();
01681             foreach ($this->aDiscounts as $oDiscount) {
01682                 $oDiscount->fDiscount = $oLang->formatCurrency( $oDiscount->dDiscount, $this->getBasketCurrency() );
01683             }
01684         }
01685     }
01686 
01687 
01693     protected function _canSaveBasket()
01694     {
01695         $blCanSave = !$this->getConfig()->getConfigParam( 'blPerfNoBasketSaving' );
01696         return $blCanSave;
01697     }
01698 
01704     public function load()
01705     {
01706         $oUser = $this->getBasketUser();
01707         if ( !$oUser ) {
01708             return;
01709         }
01710 
01711         $oBasket = $oUser->getBasket( 'savedbasket' );
01712 
01713         // restoring from saved history
01714         $aSavedItems = $oBasket->getItems();
01715         foreach ( $aSavedItems as $oItem ) {
01716             try {
01717                 $oSelList = $oItem->getSelList();
01718 
01719                 $this->addToBasket( $oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true );
01720             } catch( oxArticleException $oEx ) {
01721                 // caught and ignored
01722             }
01723         }
01724     }
01725 
01731     protected function _save()
01732     {
01733         if ( $this->_canSaveBasket() ) {
01734 
01735             if ( $oUser = $this->getBasketUser() ) {
01736                 //first delete all contents
01737                 //#2039
01738                 $oSavedBasket = $oUser->getBasket( 'savedbasket' );
01739                 $oSavedBasket->delete();
01740 
01741                 //then save
01742                 foreach ( $this->_aBasketContents as $oBasketItem ) {
01743                     // discount or bundled products will be added automatically if available
01744                     if ( !$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle() ) {
01745                        $oSavedBasket->addItemToBasket( $oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams() );
01746                     }
01747                 }
01748             }
01749         }
01750     }
01751 
01759     protected function _deleteSavedBasket()
01760     {
01761         // deleting basket if session user available
01762         if ( $oUser = $this->getBasketUser() ) {
01763             $oUser->getBasket( 'savedbasket' )->delete();
01764         }
01765 
01766         // basket exclude
01767         if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' )) {
01768             $this->setBasketRootCatId(null);
01769         }
01770     }
01771 
01777     protected function _findDelivCountry()
01778     {
01779         $myConfig = $this->getConfig();
01780         $oUser    = $this->getBasketUser();
01781 
01782         $sDelivCountry = null;
01783 
01784         if ( !$oUser ) {
01785             // don't calculate if not logged in unless specified otherwise
01786             $aHomeCountry = $myConfig->getConfigParam( 'aHomeCountry' );
01787             if ( $myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) && is_array( $aHomeCountry ) ) {
01788                 $sDelivCountry = current( $aHomeCountry );
01789             }
01790         } else {
01791 
01792             // ok, logged in
01793             if ( $sCountryId = $myConfig->getGlobalParameter( 'delcountryid' ) ) {
01794                 $sDelivCountry = $sCountryId;
01795             } elseif ( $sAddressId = oxSession::getVar( 'deladrid' ) ) {
01796 
01797                 $oDelAdress = oxNew( 'oxaddress' );
01798                 if ( $oDelAdress->load( $sAddressId ) ) {
01799                     $sDelivCountry = $oDelAdress->oxaddress__oxcountryid->value;
01800                 }
01801             }
01802 
01803             // still not found ?
01804             if ( !$sDelivCountry ) {
01805                 $sDelivCountry = $oUser->oxuser__oxcountryid->value;
01806             }
01807         }
01808 
01809         return $sDelivCountry;
01810     }
01811 
01817     public function deleteBasket()
01818     {
01819         $this->_aBasketContents = array();
01820         $this->getSession()->delBasket();
01821 
01822         if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01823             $this->getSession()->getBasketReservations()->discardReservations();
01824         }
01825 
01826         // merging basket history
01827         $this->_deleteSavedBasket();
01828     }
01829 
01837     public function setPayment( $sPaymentId = null )
01838     {
01839         $this->_sPaymentId = $sPaymentId;
01840     }
01841 
01847     public function getPaymentId()
01848     {
01849         if ( !$this->_sPaymentId ) {
01850              $this->_sPaymentId = oxSession::getVar( 'paymentid' );
01851         }
01852         return $this->_sPaymentId;
01853     }
01854 
01862     public function setShipping( $sShippingSetId = null )
01863     {
01864         $this->_sShippingSetId = $sShippingSetId;
01865         oxSession::setVar( 'sShipSet', $sShippingSetId );
01866     }
01867 
01875     public function setDeliveryPrice( $oShippingPrice = null )
01876     {
01877         $this->_oDeliveryPrice = $oShippingPrice;
01878     }
01879 
01885     public function getShippingId()
01886     {
01887         if ( !$this->_sShippingSetId ) {
01888              $this->_sShippingSetId = oxSession::getVar( 'sShipSet' );
01889         }
01890 
01891         $sActPaymentId = $this->getPaymentId();
01892         // setting default if none is set
01893         if ( !$this->_sShippingSetId && $sActPaymentId != 'oxempty' ) {
01894             $oUser = $this->getUser();
01895 
01896             // choosing first preferred delivery set
01897             list( , $sActShipSet ) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData( null, $oUser, $this );
01898             // in case nothing was found and no user set - choosing default
01899             $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ( $oUser ? null : 'oxidstandard' );
01900         } elseif ( !$this->isAdmin() && $sActPaymentId == 'oxempty' ) {
01901             // in case 'oxempty' is payment id - delivery set must be reset
01902             $this->_sShippingSetId = null;
01903         }
01904 
01905         return $this->_sShippingSetId;
01906     }
01907 
01913     public function getBasketArticles()
01914     {
01915         $aBasketArticles = array();
01916 
01917         foreach ( $this->_aBasketContents as $sItemKey => $oBasketItem ) {
01918             try {
01919                 $oProduct = $oBasketItem->getArticle( true );
01920 
01921                 if ( $this->getConfig()->getConfigParam( 'bl_perfLoadSelectLists' ) ) {
01922                     // marking chosen select list
01923                     $aSelList = $oBasketItem->getSelList();
01924                     if ( is_array( $aSelList ) && ( $aSelectlist = $oProduct->getSelectLists( $sItemKey ) ) ) {
01925                         reset( $aSelList );
01926                         while ( list( $conkey, $iSel ) = each( $aSelList ) ) {
01927                             $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01928                             $aSelectlist[$conkey][$iSel]->selected = 1;
01929                         }
01930                         $oProduct->setSelectlist( $aSelectlist );
01931                     }
01932                 }
01933             } catch ( oxNoArticleException $oEx ) {
01934                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01935                 $this->removeItem( $sItemKey );
01936                 $this->calculateBasket( true );
01937                 continue;
01938             } catch ( oxArticleInputException $oEx ) {
01939                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01940                 $this->removeItem( $sItemKey );
01941                 $this->calculateBasket( true );
01942                 continue;
01943             }
01944 
01945             $aBasketArticles[$sItemKey] = $oProduct;
01946         }
01947         return $aBasketArticles;
01948     }
01949 
01955     public function getDiscountProductsPrice()
01956     {
01957         return $this->_oDiscountProductsPriceList;
01958     }
01959 
01965     public function getProductsPrice()
01966     {
01967         if ( is_null($this->_oProductsPriceList) ) {
01968             $this->_oProductsPriceList = oxNew( 'oxPriceList' );
01969         }
01970 
01971         return $this->_oProductsPriceList;
01972     }
01973 
01979     public function getPrice()
01980     {
01981         if ( is_null($this->_oPrice) ) {
01982             $this->_oPrice = oxNew( 'oxprice' );
01983         }
01984 
01985         return $this->_oPrice;
01986     }
01987 
01994     public function getOrderId()
01995     {
01996         return $this->_sOrderId;
01997     }
01998 
02006     public function setOrderId( $sId )
02007     {
02008         $this->_sOrderId = $sId;
02009     }
02010 
02019     public function getCosts( $sId = null )
02020     {
02021         // if user want some specific cost - return it
02022         if ( $sId ) {
02023             return isset( $this->_aCosts[$sId] )?$this->_aCosts[$sId]:null;
02024         }
02025         return $this->_aCosts;
02026     }
02027 
02033     public function getVouchers()
02034     {
02035         return $this->_aVouchers;
02036     }
02037 
02043     public function getProductsCount()
02044     {
02045         return $this->_iProductsCnt;
02046     }
02047 
02053     public function getItemsCount()
02054     {
02055         return $this->_dItemsCnt;
02056     }
02057 
02063     public function getWeight()
02064     {
02065         return $this->_dWeight;
02066     }
02067 
02073     public function getContents()
02074     {
02075         return $this->_aBasketContents;
02076     }
02077 
02085     public function getProductVats( $blFormatCurrency = true )
02086     {
02087         if ( !$this->_oNotDiscountedProductsPriceList ) {
02088             return array();
02089         }
02090 
02091         $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo( $this->isCalculationModeNetto() );
02092 
02093         $oUtils = oxRegistry::getUtils();
02094         foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
02095             if ( !isset( $aVats[$sKey] ) ) {
02096                 $aVats[$sKey] = 0;
02097             }
02098             // add prices of the same discounts
02099             $aVats[$sKey] += $oUtils->fRound( $dVat, $this->_oCurrency );
02100         }
02101 
02102         if ( $blFormatCurrency ) {
02103             $oLang = oxRegistry::getLang();
02104             foreach ( $aVats as $sKey => $dVat ) {
02105                 $aVats[$sKey] = $oLang->formatCurrency( $dVat, $this->getBasketCurrency() );
02106             }
02107         }
02108 
02109         return $aVats;
02110     }
02111 
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 
02291     public function getProductsNetPrice()
02292     {
02293         return oxRegistry::getLang()->formatCurrency( $this->getNettoSum(), $this->getBasketCurrency() );
02294     }
02295 
02303     public function getFProductsPrice()
02304     {
02305         return oxRegistry::getLang()->formatCurrency( $this->getBruttoSum(), $this->getBasketCurrency() );
02306     }
02307 
02315     public function getDelCostVatPercent()
02316     {
02317         return $this->getCosts( 'oxdelivery' )->getVat();
02318     }
02319 
02327     public function getDelCostVat()
02328     {
02329         $dDelVAT = $this->getCosts( 'oxdelivery' )->getVatValue();
02330 
02331         // blShowVATForDelivery option will be used, only for displaying, but not calculation
02332         if ( $dDelVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForDelivery' )) {
02333             return oxRegistry::getLang()->formatCurrency( $dDelVAT, $this->getBasketCurrency() );
02334         }
02335         return false;
02336     }
02337 
02345     public function getDelCostNet()
02346     {
02347         $oConfig = $this->getConfig();
02348 
02349         // blShowVATForDelivery option will be used, only for displaying, but not calculation
02350         if ( $oConfig->getConfigParam( 'blShowVATForDelivery' ) && ( $this->getBasketUser() || $oConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02351             $dNetPrice = $this->getCosts( 'oxdelivery' )->getNettoPrice();
02352             if ( $dNetPrice > 0 ) {
02353                 return oxRegistry::getLang()->formatCurrency( $dNetPrice, $this->getBasketCurrency() );
02354             }
02355         }
02356         return false;
02357     }
02358 
02366     public function getPayCostVatPercent()
02367     {
02368         return $this->getCosts( 'oxpayment' )->getVat();
02369     }
02370 
02378     public function getPayCostVat()
02379     {
02380         $dPayVAT = $this->getCosts( 'oxpayment' )->getVatValue();
02381 
02382         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02383         if ( $dPayVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02384             return oxRegistry::getLang()->formatCurrency( $dPayVAT, $this->getBasketCurrency() );
02385         }
02386         return false;
02387     }
02388 
02396     public function getPayCostNet()
02397     {
02398         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02399         if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02400             $oPaymentCost = $this->getCosts( 'oxpayment' );
02401             if ( $oPaymentCost && $oPaymentCost->getNettoPrice() ) {
02402                 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxpayment' )->getNettoPrice(), $this->getBasketCurrency() );
02403             }
02404         }
02405         return false;
02406     }
02407 
02415     public function getPaymentCosts()
02416     {
02417         $oPaymentCost = $this->getCosts( 'oxpayment' );
02418         if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02419             return $oPaymentCost->getBruttoPrice();
02420         }
02421     }
02422 
02428     public function getPaymentCost()
02429     {
02430         return $this->getCosts( 'oxpayment' );
02431     }
02432 
02440     public function getFPaymentCosts()
02441     {
02442         $oPaymentCost = $this->getCosts( 'oxpayment' );
02443         if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02444             return oxRegistry::getLang()->formatCurrency( $oPaymentCost->getBruttoPrice(), $this->getBasketCurrency() );
02445         }
02446         return false;
02447     }
02448 
02454     public function getVoucherDiscValue()
02455     {
02456         if ( $this->getVoucherDiscount() ) {
02457             return $this->getVoucherDiscount()->getBruttoPrice();
02458         }
02459         return false;
02460     }
02461 
02469     public function getFVoucherDiscountValue()
02470     {
02471         if ( $oVoucherDiscount = $this->getVoucherDiscount() ) {
02472             if ( $oVoucherDiscount->getBruttoPrice() ) {
02473                 return oxRegistry::getLang()->formatCurrency( $oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency() );
02474             }
02475         }
02476         return false;
02477     }
02478 
02479 
02487     public function getWrappCostVatPercent()
02488     {
02489         return $this->getCosts( 'oxwrapping' )->getVat();
02490     }
02491 
02492 
02500     public function getGiftCardCostVatPercent()
02501     {
02502         return $this->getCosts( 'oxgiftcard' )->getVat();
02503     }
02504 
02512     public function getWrappCostVat()
02513     {
02514         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02515         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02516             $oPrice = $this->getCosts( 'oxwrapping' );
02517 
02518             if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02519                 return oxRegistry::getLang()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02520             }
02521         }
02522 
02523         return false;
02524     }
02525 
02533     public function getWrappCostNet()
02534     {
02535         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02536         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02537             $oPrice = $this->getCosts( 'oxwrapping' );
02538 
02539              if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02540                  return  oxRegistry::getLang()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02541              }
02542         }
02543 
02544         return false;
02545     }
02546 
02554     public function getFWrappingCosts()
02555     {
02556         $oPrice = $this->getCosts( 'oxwrapping' );
02557 
02558         if ( $oPrice && $oPrice->getBruttoPrice() ) {
02559             return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02560         }
02561 
02562         return false;
02563     }
02564 
02565     public function getWrappingCost()
02566     {
02567         return $this->getCosts( 'oxwrapping' );
02568     }
02569 
02577     public function getGiftCardCostVat()
02578     {
02579         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02580         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02581             $oPrice = $this->getCosts( 'oxgiftcard' );
02582 
02583             if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02584                 return oxLang::getInstance()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02585             }
02586         }
02587 
02588         return false;
02589 
02590     }
02591 
02599     public function getGiftCardCostNet()
02600     {
02601         // blShowVATForWrapping option will be used, only for displaying, but not calculation
02602         if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02603             $oPrice = $this->getCosts( 'oxgiftcard' );
02604 
02605             if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02606                 return  oxLang::getInstance()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02607             }
02608         }
02609 
02610         return false;
02611     }
02612 
02620     public function getFGiftCardCosts()
02621     {
02622         $oPrice = $this->getCosts( 'oxgiftcard' );
02623 
02624         if ( $oPrice && $oPrice->getBruttoPrice() ) {
02625             return oxLang::getInstance()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02626         }
02627         return false;
02628     }
02629 
02633     public function getGiftCardCost()
02634     {
02635         return $this->getCosts( 'oxgiftcard' );
02636     }
02637 
02645     public function getFPrice()
02646     {
02647         return oxRegistry::getLang()->formatCurrency( $this->getPrice()->getBruttoPrice(), $this->getBasketCurrency() );
02648     }
02649 
02657     public function getFDeliveryCosts()
02658     {
02659         $oPrice = $this->getCosts( 'oxdelivery' );
02660 
02661         if ( $oPrice && ( $this->getBasketUser() || $this->getConfig()->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02662             return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02663         }
02664         return false;
02665     }
02666 
02674     public function getDeliveryCosts()
02675     {
02676         if ( $oDeliveryCost = $this->getCosts( 'oxdelivery' ) ) {
02677             return $oDeliveryCost->getBruttoPrice();
02678         }
02679         return false;
02680     }
02681 
02687     public function getDeliveryCost()
02688     {
02689         return $this->getCosts( 'oxdelivery' );
02690     }
02691 
02699     public function setTotalDiscount( $dDiscount )
02700     {
02701         $this->_oTotalDiscount = oxNew( 'oxPrice' );
02702         $this->_oTotalDiscount->setBruttoPriceMode();
02703         $this->_oTotalDiscount->add( $dDiscount );
02704     }
02705 
02712     public function getPriceForPayment()
02713     {
02714         $dPrice = $this->getDiscountedProductsBruttoPrice();
02715         //#1905 not discounted products should be included in payment amount calculation
02716         if ( $oPriceList = $this->getNotDiscountProductsPrice() ) {
02717             $dPrice += $oPriceList->getBruttoSum();
02718         }
02719 
02720         // adding delivery price to final price
02721         if ( $oDeliveryPrice = $this->_aCosts['oxdelivery'] ) {
02722             $dPrice += $oDeliveryPrice->getBruttoPrice();
02723         }
02724 
02725         return $dPrice;
02726     }
02727 
02728 
02734     public function _getDiscountedProductsSum()
02735     {
02736         if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02737             $dPrice = $oProductsPrice->getSum( $this->isCalculationModeNetto() );
02738         }
02739 
02740         // substracting total discount
02741         if ( $oPrice = $this->getTotalDiscount() ) {
02742             $dPrice -= $oPrice->getPrice();
02743         }
02744 
02745         if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02746             $dPrice -= $oVoucherPrice->getPrice();
02747         }
02748 
02749         return $dPrice;
02750     }
02751 
02757     public function getDiscountedProductsBruttoPrice()
02758     {
02759         if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02760             $dPrice = $oProductsPrice->getBruttoSum();
02761         }
02762 
02763         // substracting total discount
02764         if ( $oPrice = $this->getTotalDiscount() ) {
02765             $dPrice -= $oPrice->getBruttoPrice();
02766         }
02767 
02768         if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02769             $dPrice -= $oVoucherPrice->getBruttoPrice();
02770         }
02771 
02772         return $dPrice;
02773     }
02774 
02780     public function isBelowMinOrderPrice()
02781     {
02782         $blIsBelowMinOrderPrice = false;
02783         $sConfValue = $this->getConfig()->getConfigParam( 'iMinOrderPrice' );
02784         if ( is_numeric($sConfValue) && $this->getProductsCount() ) {
02785             $dMinOrderPrice = oxPrice::getPriceInActCurrency( ( double ) $sConfValue );
02786             $dNotDiscountedProductPrice = 0;
02787             if ( $oPrice = $this->getNotDiscountProductsPrice() ) {
02788                 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02789             }
02790             $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02791         }
02792 
02793         return $blIsBelowMinOrderPrice;
02794 
02795     }
02796 
02805     public function getArtStockInBasket( $sArtId, $sExpiredArtId = null )
02806     {
02807         $dArtStock = 0;
02808         foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
02809             if ( $oOrderArticle && ( $sExpiredArtId == null || $sExpiredArtId != $sItemKey ) ) {
02810                 if ( $oOrderArticle->getArticle( true )->getId() == $sArtId ) {
02811                     $dArtStock += $oOrderArticle->getAmount();
02812                 }
02813             }
02814         }
02815 
02816         return $dArtStock;
02817     }
02818 
02826     public function canAddProductToBasket( $sProductId )
02827     {
02828         $blCanAdd = null;
02829 
02830         // if basket category is not set..
02831         if ( $this->_sBasketCategoryId === null ) {
02832             $oCat = null;
02833 
02834             // request category
02835             if ( $oView = $this->getConfig()->getActiveView() ) {
02836                 if ( $oCat = $oView->getActiveCategory() ) {
02837                     if ( !$this->_isProductInRootCategory( $sProductId, $oCat->oxcategories__oxrootid->value ) ) {
02838                         $oCat = null;
02839                     } else {
02840                         $blCanAdd = true;
02841                     }
02842                 }
02843             }
02844 
02845             // product main category
02846             if ( !$oCat ) {
02847                 $oProduct = oxNew( "oxarticle" );
02848                 if ( $oProduct->load( $sProductId ) ) {
02849                     $oCat = $oProduct->getCategory();
02850                 }
02851             }
02852 
02853             // root category id
02854             if ( $oCat ) {
02855                 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02856             }
02857         }
02858 
02859         // avoiding double check..
02860         if ( $blCanAdd === null ) {
02861             $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory( $sProductId, $this->getBasketRootCatId() ) : true;
02862         }
02863 
02864         return $blCanAdd;
02865     }
02866 
02875     protected function _isProductInRootCategory( $sProductId, $sRootCatId )
02876     {
02877         $sO2CTable = getViewName( 'oxobject2category' );
02878         $sCatTable = getViewName( 'oxcategories' );
02879 
02880         $oDb = oxDb::getDb();
02881         $sParentId  = $oDb->getOne( "select oxparentid from oxarticles where oxid = ".$oDb->quote( $sProductId ) );
02882         $sProductId = $sParentId ? $sParentId : $sProductId;
02883 
02884         $sQ = "select 1 from {$sO2CTable}
02885                  left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02886                  where {$sO2CTable}.oxobjectid = ".$oDb->quote( $sProductId )." and
02887                        {$sCatTable}.oxrootid = ".$oDb->quote( $sRootCatId );
02888 
02889         return (bool) $oDb->getOne( $sQ );
02890     }
02891 
02899     public function setBasketRootCatId($sRoot)
02900     {
02901         $this->_sBasketCategoryId = $sRoot;
02902     }
02903 
02909     public function getBasketRootCatId()
02910     {
02911         return $this->_sBasketCategoryId;
02912     }
02913 
02921     public function setCatChangeWarningState( $blShow )
02922     {
02923         $this->_blShowCatChangeWarning = $blShow;
02924     }
02925 
02931     public function showCatChangeWarning()
02932     {
02933         return $this->_blShowCatChangeWarning;
02934     }
02935 
02943     public function setTsProductId( $sProductId )
02944     {
02945         $this->_sTsProductId = $sProductId;
02946     }
02947 
02953     public function getTsProductId()
02954     {
02955         return $this->_sTsProductId;
02956     }
02957 
02965     public function getFTsProtectionCosts()
02966     {
02967         $oProtectionCost = $this->getCosts( 'oxtsprotection' );
02968         if ( $oProtectionCost && $oProtectionCost->getBruttoPrice() ) {
02969             return oxRegistry::getLang()->formatCurrency( $oProtectionCost->getBruttoPrice(), $this->getBasketCurrency() );
02970         }
02971         return false;
02972     }
02973 
02981     public function getTsProtectionVatPercent()
02982     {
02983         return $this->getCosts( 'oxtsprotection' )->getVat();
02984     }
02985 
02993     public function getTsProtectionVat()
02994     {
02995         $dProtectionVAT = $this->getCosts( 'oxtsprotection' )->getVatValue();
02996         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
02997         if ( $dProtectionVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02998             return oxRegistry::getLang()->formatCurrency( $dProtectionVAT, $this->getBasketCurrency() );
02999         }
03000         return false;
03001     }
03002 
03010     public function getTsProtectionNet()
03011     {
03012         // blShowVATForPayCharge option will be used, only for displaying, but not calculation
03013         if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
03014             return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxtsprotection' )->getNettoPrice(), $this->getBasketCurrency() );
03015         }
03016         return false;
03017     }
03018 
03026     public function getTsProtectionCosts()
03027     {
03028         $oProtection = $this->getCosts( 'oxtsprotection' );
03029         if ( $oProtection ) {
03030             return $oProtection->getBruttoPrice();
03031         }
03032         return false;
03033     }
03034 
03040     public function getTrustedShopProtectionCost()
03041     {
03042         return $this->getCosts( 'oxtsprotection' );
03043     }
03044 
03045 
03051     public function getNotDiscountProductsPrice()
03052     {
03053         return $this->_oNotDiscountedProductsPriceList;
03054     }
03055 
03069     protected function _addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId )
03070     {
03071         if ( !$blOverride ) {
03072             $this->_blNewITemAdded = null;
03073             oxSession::setVar( "blAddedNewItem", true );
03074         }
03075     }
03076 
03082     public function __wakeUp()
03083     {
03084         $this->_blNewITemAdded = null;
03085         $this->_isCalculationModeNetto = null;
03086     }
03087 
03093     public function isNewItemAdded()
03094     {
03095         if ( $this->_blNewITemAdded == null ) {
03096             $this->_blNewITemAdded = (bool) oxSession::getVar( "blAddedNewItem" );
03097             oxSession::deleteVar( "blAddedNewItem" );
03098         }
03099         return $this->_blNewITemAdded;
03100     }
03101 
03107     public function hasDownloadableProducts()
03108     {
03109         $this->_blDownloadableProducts = false;
03110         foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
03111             if ( $oOrderArticle->getArticle( false ) && $oOrderArticle->getArticle( false )->isDownloadable() ) {
03112                 $this->_blDownloadableProducts = true;
03113                 break;
03114             }
03115         }
03116 
03117         return $this->_blDownloadableProducts;
03118     }
03119 
03125     public function getMinOrderPrice()
03126     {
03127         return oxPrice::getPriceInActCurrency( $this->getConfig()->getConfigParam( 'iMinOrderPrice' ) );
03128     }
03129 
03130 }