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
00382 if ( !$this->isEnabled() )
00383 return null;
00384
00385
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
00399 unset( $this->_aBasketContents[$sOldBasketItemId] );
00400
00401 $blOverride = false;
00402 } else {
00403
00404 $this->_changeBasketItemKey( $sOldBasketItemId, $sItemId );
00405 }
00406 }
00407
00408
00409 $blRemoveItem = false;
00410
00411
00412 $oEx = null;
00413
00414 if ( isset( $this->_aBasketContents[$sItemId] ) ) {
00415
00416
00417 try {
00418
00419 $this->_aBasketContents[$sItemId]->setStockCheckStatus( $this->getStockCheckMode() );
00420
00421
00422 $this->_aBasketContents[$sItemId]->setAmount( $dAmount, $blOverride, $sItemId );
00423 } catch( oxOutOfStockException $oEx ) {
00424
00425 }
00426
00427 } else {
00428
00429 $oBasketItem = oxNew( 'oxbasketitem' );
00430 try {
00431 $oBasketItem->setStockCheckStatus( $this->getStockCheckMode() );
00432 $oBasketItem->init( $sProductID, $dAmount, $aSel, $aPersParam, $blBundle );
00433 } catch( oxNoArticleException $oEx ) {
00434
00435
00436 $blRemoveItem = true;
00437
00438 } catch( oxOutOfStockException $oEx ) {
00439
00440 } catch ( oxArticleInputException $oEx ) {
00441
00442 $blRemoveItem = true;
00443 }
00444
00445 $this->_aBasketContents[$sItemId] = $oBasketItem;
00446 }
00447
00448
00449 if ( $this->_aBasketContents[$sItemId]->getAmount() == 0 || $blRemoveItem ) {
00450 $this->removeItem( $sItemId );
00451 } elseif ( $blBundle ) {
00452
00453 $this->_aBasketContents[$sItemId]->setBundle( true );
00454 }
00455
00456
00457 $this->onUpdate();
00458
00459 if ( $oEx ) {
00460 throw $oEx;
00461 }
00462
00463
00464 if (!$blBundle) {
00465 $this->_addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId );
00466 }
00467
00468
00469 return $this->_aBasketContents[$sItemId];
00470 }
00471
00479 public function addOrderArticleToBasket( $oOrderArticle )
00480 {
00481
00482 if ( $oOrderArticle->oxorderarticles__oxamount->value > 0 && !$oOrderArticle->isBundle() ) {
00483
00484 $this->_isForOrderRecalculation = true;
00485 $sItemId = $oOrderArticle->getId();
00486
00487
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
00494 $this->onUpdate();
00495
00496 return $this->_aBasketContents[$sItemId];
00497 } elseif ( $oOrderArticle->isBundle() ) {
00498
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
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
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
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
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
00693 foreach ( $this->_aBasketContents as $key => $oBasketItem ) {
00694 try {
00695
00696 if ( !$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle() ) {
00697 $aBundles = $this->_getItemBundles( $oBasketItem, $aBundles );
00698 } else {
00699 continue;
00700 }
00701
00702
00703 $aArtBundles = $this->_getArticleBundles( $oBasketItem );
00704
00705
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
00717 $aBundles = $this->_getBasketBundles( $aBundles );
00718
00719
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
00742 }
00743 }
00744 }
00745
00746 }
00747
00753 protected function _calcItemsPrice()
00754 {
00755
00756 $this->setSkipDiscounts( false );
00757 $this->_iProductsCnt = 0;
00758 $this->_dItemsCnt = 0;
00759 $this->_dWeight = 0;
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
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
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
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
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
00874 $oUser = $this->getBasketUser();
00875
00876 if ( !$oUser && !$myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) {
00877 return $oDeliveryPrice;
00878 }
00879
00880
00881
00882
00883 $fDelVATPercent = 0;
00884 $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00885 $oDeliveryPrice->setVat( $fDelVATPercent );
00886
00887
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
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
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
00985 protected function _calcTotalPrice()
00986 {
00987
00988 $dprice = $this->_dBruttoSum;
00989 $this->_oPrice = oxNew( 'oxPrice' );
00990 $this->_oPrice->setBruttoPriceMode();
00991 $this->_oPrice->setPrice( $dprice );
00992
00993
00994 if ( $dprice && !$this->isCalculationModeNetto() ) {
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007 $this->_oPrice->subtract( $this->_oTotalDiscount->getBruttoPrice() );
01008
01009
01010 if ($oVoucherDisc = $this->getVoucherDiscount()) {
01011 $this->_oPrice->subtract( $oVoucherDisc->getBruttoPrice() );
01012 }
01013 }
01014
01015
01016 if ( isset( $this->_aCosts['oxdelivery'] ) ) {
01017 $this->_oPrice->add( $this->_aCosts['oxdelivery']->getBruttoPrice() );
01018 }
01019
01020
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
01029 if ( isset( $this->_aCosts['oxpayment'] ) ) {
01030 $this->_oPrice->add( $this->_aCosts['oxpayment']->getBruttoPrice() );
01031 }
01032
01033
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
01066 $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() ) - $this->_oTotalDiscount->getPrice();
01067
01068
01069 if ( count( $this->_aVouchers ) ) {
01070 $oLang = oxRegistry::getLang();
01071 foreach ( $this->_aVouchers as $sVoucherId => $oStdVoucher ) {
01072 $oVoucher = oxNew( 'oxvoucher' );
01073 try {
01074 $oVoucher->load( $oStdVoucher->sVoucherId );
01075
01076 if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01077 $oVoucher->checkBasketVoucherAvailability( $this->_aVouchers, $dPrice );
01078 $oVoucher->checkUserAvailability( $this->getBasketUser() );
01079 }
01080
01081
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
01099 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01100 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01101 }
01102 }
01103
01104
01105 $this->_oVoucherDiscount->add( $dVoucherdiscount );
01106
01107
01108 $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency( $dVoucherdiscount, $this->getBasketCurrency() );
01109 $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01110
01111
01112 $dPrice = $dPrice - $dVoucherdiscount;
01113
01114
01115
01116 } catch ( oxVoucherException $oEx ) {
01117
01118
01119 $oVoucher->unMarkAsReserved();
01120 unset( $this->_aVouchers[$sVoucherId] );
01121
01122
01123 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01124 }
01125 }
01126 }
01127 }
01128 }
01129
01136 protected function _applyDiscounts()
01137 {
01138 $dBruttoPrice = 0;
01139
01140
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
01155 $this->setNettoSum($this->getProductsPrice()->getSum());
01156 $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedBruttoPrice + $dVatSum);
01157 } else {
01158
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
01205 $this->_aDiscounts = array();
01206
01207
01208 $dOldprice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01209
01210
01211 if ( $this->_oTotalDiscount !== null && isset($this->_isForOrderRecalculation) && $this->_isForOrderRecalculation ) {
01212
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
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
01230 $oStdDiscount = $oDiscount->getSimpleDiscount();
01231
01232
01233 if ( $oDiscount->oxdiscount__oxaddsumtype->value == 'itm' ) {
01234 continue;
01235 }
01236
01237
01238 $oStdDiscount->dDiscount = $oDiscount->getAbsValue( $dOldprice );
01239
01240
01241
01242 $dVatPart = 100 - $oDiscount->getPercentage( $dOldprice );
01243
01244
01245 if ( $dOldprice < $oStdDiscount->dDiscount ) {
01246 $oStdDiscount->dDiscount = $dOldprice;
01247 $dVatPart = 0;
01248 }
01249
01250
01251 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01252 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01253 }
01254
01255
01256 if ($oStdDiscount->dDiscount != 0) {
01257 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01258
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
01279 if ( $oDiscount->sType == 'itm' ) {
01280 continue;
01281 }
01282
01283
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
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
01363 $oPaymentPrice = oxNew( 'oxPrice' );
01364
01365
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
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
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
01449 $this->_save();
01450
01451
01452 $this->_clearBundles();
01453
01454
01455 $this->_addBundles();
01456
01457
01458 if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01459 $this->getSession()->getBasketReservations()->reserveBasket($this);
01460 }
01461
01462
01463 $this->_calcItemsPrice();
01464
01465
01466 $this->_calcBasketDiscount();
01467
01468
01469 $this->_calcBasketTotalDiscount();
01470
01471
01472 $this->_calcVoucherDiscount();
01473
01474
01475 $this->_applyDiscounts();
01476
01477
01478
01479 $this->setCost( 'oxdelivery', $this->_calcDeliveryCost() );
01480
01481
01482 $this->setCost( 'oxwrapping', $this->_calcBasketWrapping() );
01483
01484 $this->setCost( 'oxgiftcard', $this->_calcBasketGiftCard() );
01485
01486
01487 $this->setCost( 'oxpayment', $this->_calcPaymentCost() );
01488
01489
01490 $this->setCost( 'oxtsprotection', $this->_calcTsProtectionCost() );
01491
01492
01493 $this->_calcTotalPrice();
01494
01495
01496 $this->formatDiscount();
01497
01498
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
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
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
01604
01605 $dPrice = 0;
01606 if ( $this->_oDiscountProductsPriceList ) {
01607 $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01608 }
01609
01610 try {
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
01624 $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
01625 } catch ( oxVoucherException $oEx ) {
01626
01627
01628 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, true );
01629 }
01630
01631 $this->onUpdate();
01632 }
01633
01641 public function removeVoucher( $sVoucherId )
01642 {
01643
01644 if ( isset( $this->_aVouchers[$sVoucherId] ) ) {
01645
01646 $oVoucher = oxNew( 'oxvoucher' );
01647 $oVoucher->load( $sVoucherId );
01648
01649 $oVoucher->unMarkAsReserved();
01650
01651
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
01677
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
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
01722 }
01723 }
01724 }
01725
01731 protected function _save()
01732 {
01733 if ( $this->_canSaveBasket() ) {
01734
01735 if ( $oUser = $this->getBasketUser() ) {
01736
01737
01738 $oSavedBasket = $oUser->getBasket( 'savedbasket' );
01739 $oSavedBasket->delete();
01740
01741
01742 foreach ( $this->_aBasketContents as $oBasketItem ) {
01743
01744 if ( !$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle() ) {
01745 $oSavedBasket->addItemToBasket( $oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams() );
01746 }
01747 }
01748 }
01749 }
01750 }
01751
01763
01764
01765
01766
01767
01768
01769
01770
01771
01779 protected function _deleteSavedBasket()
01780 {
01781
01782 if ( $oUser = $this->getBasketUser() ) {
01783 $oUser->getBasket( 'savedbasket' )->delete();
01784 }
01785
01786
01787 if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' )) {
01788 $this->setBasketRootCatId(null);
01789 }
01790 }
01791
01797 protected function _findDelivCountry()
01798 {
01799 $myConfig = $this->getConfig();
01800 $oUser = $this->getBasketUser();
01801
01802 $sDelivCountry = null;
01803
01804 if ( !$oUser ) {
01805
01806 $aHomeCountry = $myConfig->getConfigParam( 'aHomeCountry' );
01807 if ( $myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) && is_array( $aHomeCountry ) ) {
01808 $sDelivCountry = current( $aHomeCountry );
01809 }
01810 } else {
01811
01812
01813 if ( $sCountryId = $myConfig->getGlobalParameter( 'delcountryid' ) ) {
01814 $sDelivCountry = $sCountryId;
01815 } elseif ( $sAddressId = oxSession::getVar( 'deladrid' ) ) {
01816
01817 $oDelAdress = oxNew( 'oxaddress' );
01818 if ( $oDelAdress->load( $sAddressId ) ) {
01819 $sDelivCountry = $oDelAdress->oxaddress__oxcountryid->value;
01820 }
01821 }
01822
01823
01824 if ( !$sDelivCountry ) {
01825 $sDelivCountry = $oUser->oxuser__oxcountryid->value;
01826 }
01827 }
01828
01829 return $sDelivCountry;
01830 }
01831
01837 public function deleteBasket()
01838 {
01839 $this->_aBasketContents = array();
01840 $this->getSession()->delBasket();
01841
01842 if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01843 $this->getSession()->getBasketReservations()->discardReservations();
01844 }
01845
01846
01847 $this->_deleteSavedBasket();
01848 }
01849
01857 public function setPayment( $sPaymentId = null )
01858 {
01859 $this->_sPaymentId = $sPaymentId;
01860 }
01861
01867 public function getPaymentId()
01868 {
01869 if ( !$this->_sPaymentId ) {
01870 $this->_sPaymentId = oxSession::getVar( 'paymentid' );
01871 }
01872 return $this->_sPaymentId;
01873 }
01874
01882 public function setShipping( $sShippingSetId = null )
01883 {
01884 $this->_sShippingSetId = $sShippingSetId;
01885 oxSession::setVar( 'sShipSet', $sShippingSetId );
01886 }
01887
01895 public function setDeliveryPrice( $oShippingPrice = null )
01896 {
01897 $this->_oDeliveryPrice = $oShippingPrice;
01898 }
01899
01905 public function getShippingId()
01906 {
01907 if ( !$this->_sShippingSetId ) {
01908 $this->_sShippingSetId = oxSession::getVar( 'sShipSet' );
01909 }
01910
01911 $sActPaymentId = $this->getPaymentId();
01912
01913 if ( !$this->_sShippingSetId && $sActPaymentId != 'oxempty' ) {
01914 $oUser = $this->getUser();
01915
01916
01917 list( , $sActShipSet ) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData( null, $oUser, $this );
01918
01919 $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ( $oUser ? null : 'oxidstandard' );
01920 } elseif ( !$this->isAdmin() && $sActPaymentId == 'oxempty' ) {
01921
01922 $this->_sShippingSetId = null;
01923 }
01924
01925 return $this->_sShippingSetId;
01926 }
01927
01933 public function getBasketArticles()
01934 {
01935 $aBasketArticles = array();
01936
01937 foreach ( $this->_aBasketContents as $sItemKey => $oBasketItem ) {
01938 try {
01939 $oProduct = $oBasketItem->getArticle( true );
01940
01941 if ( $this->getConfig()->getConfigParam( 'bl_perfLoadSelectLists' ) ) {
01942
01943 $aSelList = $oBasketItem->getSelList();
01944 if ( is_array( $aSelList ) && ( $aSelectlist = $oProduct->getSelectLists( $sItemKey ) ) ) {
01945 reset( $aSelList );
01946 while ( list( $conkey, $iSel ) = each( $aSelList ) ) {
01947 $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01948 $aSelectlist[$conkey][$iSel]->selected = 1;
01949 }
01950 $oProduct->setSelectlist( $aSelectlist );
01951 }
01952 }
01953 } catch ( oxNoArticleException $oEx ) {
01954 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01955 $this->removeItem( $sItemKey );
01956 $this->calculateBasket( true );
01957 continue;
01958 } catch ( oxArticleInputException $oEx ) {
01959 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01960 $this->removeItem( $sItemKey );
01961 $this->calculateBasket( true );
01962 continue;
01963 }
01964
01965 $aBasketArticles[$sItemKey] = $oProduct;
01966 }
01967 return $aBasketArticles;
01968 }
01969
01975 public function getDiscountProductsPrice()
01976 {
01977 return $this->_oDiscountProductsPriceList;
01978 }
01979
01985 public function getProductsPrice()
01986 {
01987 if ( is_null($this->_oProductsPriceList) ) {
01988 $this->_oProductsPriceList = oxNew( 'oxPriceList' );
01989 }
01990
01991 return $this->_oProductsPriceList;
01992 }
01993
01999 public function getPrice()
02000 {
02001 if ( is_null($this->_oPrice) ) {
02002 $this->_oPrice = oxNew( 'oxprice' );
02003 }
02004
02005 return $this->_oPrice;
02006 }
02007
02014 public function getOrderId()
02015 {
02016 return $this->_sOrderId;
02017 }
02018
02026 public function setOrderId( $sId )
02027 {
02028 $this->_sOrderId = $sId;
02029 }
02030
02039 public function getCosts( $sId = null )
02040 {
02041
02042 if ( $sId ) {
02043 return isset( $this->_aCosts[$sId] )?$this->_aCosts[$sId]:null;
02044 }
02045 return $this->_aCosts;
02046 }
02047
02053 public function getVouchers()
02054 {
02055 return $this->_aVouchers;
02056 }
02057
02063 public function getProductsCount()
02064 {
02065 return $this->_iProductsCnt;
02066 }
02067
02073 public function getItemsCount()
02074 {
02075 return $this->_dItemsCnt;
02076 }
02077
02083 public function getWeight()
02084 {
02085 return $this->_dWeight;
02086 }
02087
02093 public function getContents()
02094 {
02095 return $this->_aBasketContents;
02096 }
02097
02105 public function getProductVats( $blFormatCurrency = true)
02106 {
02107 if ( !$this->_oNotDiscountedProductsPriceList ) {
02108 return array();
02109 }
02110
02111 $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo( $this->isCalculationModeNetto() );
02112
02113 $oUtils = oxRegistry::getUtils();
02114 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
02115 if ( !isset( $aVats[$sKey] ) ) {
02116 $aVats[$sKey] = 0;
02117 }
02118
02119 $aVats[$sKey] += $oUtils->fRound( $dVat, $this->_oCurrency );
02120 }
02121
02122 if ( $blFormatCurrency ) {
02123 $oLang = oxRegistry::getLang();
02124 foreach ( $aVats as $sKey => $dVat ) {
02125 $aVats[$sKey] = $oLang->formatCurrency( $dVat, $this->getBasketCurrency() );
02126 }
02127 }
02128
02129 return $aVats;
02130 }
02131
02137 public function getDiscountedNettoPrice()
02138 {
02139 if ( $this->_oNotDiscountedProductsPriceList ) {
02140 return $this->_dDiscountedProductNettoPrice + $this->_oNotDiscountedProductsPriceList->getNettoSum();
02141 }
02142 return false;
02143 }
02144
02152 public function setCardMessage( $sMessage )
02153 {
02154 $this->_sCardMessage = $sMessage;
02155 }
02156
02162 public function getCardMessage()
02163 {
02164 return $this->_sCardMessage;
02165 }
02166
02174 public function setCardId( $sCardId )
02175 {
02176 $this->_sCardId = $sCardId;
02177 }
02178
02184 public function getCardId()
02185 {
02186 return $this->_sCardId;
02187 }
02188
02194 public function getCard()
02195 {
02196 $oCard = null;
02197 if ( $sCardId = $this->getCardId() ) {
02198 $oCard = oxNew( 'oxwrapping' );
02199 $oCard->load( $sCardId );
02200 $oCard->setWrappingVat( $this->getAdditionalServicesVatPercent() );
02201 }
02202 return $oCard;
02203 }
02204
02210 public function getTotalDiscount()
02211 {
02212 return $this->_oTotalDiscount;
02213 }
02214
02220 public function getDiscounts()
02221 {
02222 if ( $this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
02223 return null;
02224 }
02225
02226 return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
02227 }
02228
02234 public function getVoucherDiscount()
02235 {
02236 if ($this->getConfig()->getConfigParam( 'bl_showVouchers' )) {
02237 return $this->_oVoucherDiscount;
02238 }
02239 return null;
02240 }
02241
02249 public function setBasketCurrency( $oCurrency )
02250 {
02251 $this->_oCurrency = $oCurrency;
02252 }
02253
02259 public function getBasketCurrency()
02260 {
02261 if ( $this->_oCurrency === null ) {
02262 $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
02263 }
02264
02265 return $this->_oCurrency;
02266 }
02267
02275 public function setSkipVouchersChecking( $blSkipChecking = null )
02276 {
02277 $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
02278 }
02279
02285 public function hasSkipedDiscount()
02286 {
02287 return $this->_blSkipDiscounts;
02288 }
02289
02297 public function setSkipDiscounts( $blSkip )
02298 {
02299 $this->_blSkipDiscounts = $blSkip;
02300 }
02301
02307 public function getProductsNetPrice()
02308 {
02309 return oxRegistry::getLang()->formatCurrency( $this->getNettoSum(), $this->getBasketCurrency() );
02310 }
02311
02317 public function getFProductsPrice()
02318 {
02319 return oxRegistry::getLang()->formatCurrency( $this->getBruttoSum(), $this->getBasketCurrency() );
02320 }
02321
02327 public function getDelCostVatPercent()
02328 {
02329 return $this->getCosts( 'oxdelivery' )->getVat();
02330 }
02331
02337 public function getDelCostVat()
02338 {
02339 $dDelVAT = $this->getCosts( 'oxdelivery' )->getVatValue();
02340
02341
02342 if ( $dDelVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForDelivery' )) {
02343 return oxRegistry::getLang()->formatCurrency( $dDelVAT, $this->getBasketCurrency() );
02344 }
02345 return false;
02346 }
02347
02353 public function getDelCostNet()
02354 {
02355 $oConfig = $this->getConfig();
02356
02357
02358 if ( $oConfig->getConfigParam( 'blShowVATForDelivery' ) && ( $this->getBasketUser() || $oConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02359 $dNetPrice = $this->getCosts( 'oxdelivery' )->getNettoPrice();
02360 if ( $dNetPrice > 0 ) {
02361 return oxRegistry::getLang()->formatCurrency( $dNetPrice, $this->getBasketCurrency() );
02362 }
02363 }
02364 return false;
02365 }
02366
02372 public function getPayCostVatPercent()
02373 {
02374 return $this->getCosts( 'oxpayment' )->getVat();
02375 }
02376
02382 public function getPayCostVat()
02383 {
02384 $dPayVAT = $this->getCosts( 'oxpayment' )->getVatValue();
02385
02386
02387 if ( $dPayVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02388 return oxRegistry::getLang()->formatCurrency( $dPayVAT, $this->getBasketCurrency() );
02389 }
02390 return false;
02391 }
02392
02398 public function getPayCostNet()
02399 {
02400
02401 if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02402 $oPaymentCost = $this->getCosts( 'oxpayment' );
02403 if ( $oPaymentCost && $oPaymentCost->getNettoPrice() ) {
02404 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxpayment' )->getNettoPrice(), $this->getBasketCurrency() );
02405 }
02406 }
02407 return false;
02408 }
02409
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 getFPaymentCosts()
02429 {
02430 $oPaymentCost = $this->getCosts( 'oxpayment' );
02431 if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02432 return oxRegistry::getLang()->formatCurrency( $oPaymentCost->getBruttoPrice(), $this->getBasketCurrency() );
02433 }
02434 return false;
02435 }
02436
02442 public function getVoucherDiscValue()
02443 {
02444 if ( $this->getVoucherDiscount() ) {
02445 return $this->getVoucherDiscount()->getBruttoPrice();
02446 }
02447 return false;
02448 }
02449
02455 public function getFVoucherDiscountValue()
02456 {
02457 if ( $oVoucherDiscount = $this->getVoucherDiscount() ) {
02458 if ( $oVoucherDiscount->getBruttoPrice() ) {
02459 return oxRegistry::getLang()->formatCurrency( $oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency() );
02460 }
02461 }
02462 return false;
02463 }
02464
02465
02471 public function getWrappCostVatPercent()
02472 {
02473 return $this->getCosts( 'oxwrapping' )->getVat();
02474 }
02475
02476
02482 public function getGiftCardCostVatPercent()
02483 {
02484 return $this->getCosts( 'oxgiftcard' )->getVat();
02485 }
02486
02492 public function getWrappCostVat()
02493 {
02494
02495 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02496 $oPrice = $this->getCosts( 'oxwrapping' );
02497
02498 if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02499 return oxRegistry::getLang()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02500 }
02501 }
02502
02503 return false;
02504 }
02505
02511 public function getWrappCostNet()
02512 {
02513
02514 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02515 $oPrice = $this->getCosts( 'oxwrapping' );
02516
02517 if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02518 return oxRegistry::getLang()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02519 }
02520 }
02521
02522 return false;
02523 }
02524
02530 public function getFWrappingCosts()
02531 {
02532 $oPrice = $this->getCosts( 'oxwrapping' );
02533
02534 if ( $oPrice && $oPrice->getBruttoPrice() ) {
02535 return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02536 }
02537
02538 return false;
02539 }
02540
02541
02547 public function getGiftCardCostVat()
02548 {
02549
02550 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02551 $oPrice = $this->getCosts( 'oxgiftcard' );
02552
02553 if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02554 return oxLang::getInstance()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02555 }
02556 }
02557
02558 return false;
02559
02560 }
02561
02567 public function getGiftCardCostNet()
02568 {
02569
02570 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02571 $oPrice = $this->getCosts( 'oxgiftcard' );
02572
02573 if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02574 return oxLang::getInstance()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02575 }
02576 }
02577
02578 return false;
02579 }
02580
02586 public function getFGiftCardCosts()
02587 {
02588 $oPrice = $this->getCosts( 'oxgiftcard' );
02589
02590 if ( $oPrice && $oPrice->getBruttoPrice() ) {
02591 return oxLang::getInstance()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02592 }
02593 return false;
02594 }
02595
02601 public function getFPrice()
02602 {
02603 return oxRegistry::getLang()->formatCurrency( $this->getPrice()->getBruttoPrice(), $this->getBasketCurrency() );
02604 }
02605
02611 public function getFDeliveryCosts()
02612 {
02613 $oPrice = $this->getCosts( 'oxdelivery' );
02614
02615 if ( $oPrice && ( $this->getBasketUser() || $this->getConfig()->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02616 return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02617 }
02618 return false;
02619 }
02620
02626 public function getDeliveryCosts()
02627 {
02628 if ( $oDeliveryCost = $this->getCosts( 'oxdelivery' ) ) {
02629 return $oDeliveryCost->getBruttoPrice();
02630 }
02631 return false;
02632 }
02633
02641 public function setTotalDiscount( $dDiscount )
02642 {
02643 $this->_oTotalDiscount = oxNew( 'oxPrice' );
02644 $this->_oTotalDiscount->setBruttoPriceMode();
02645 $this->_oTotalDiscount->add( $dDiscount );
02646 }
02647
02654 public function getPriceForPayment()
02655 {
02656 $dPrice = $this->getDiscountedProductsBruttoPrice();
02657
02658 if ( $oPriceList = $this->getNotDiscountProductsPrice() ) {
02659 $dPrice += $oPriceList->getBruttoSum();
02660 }
02661
02662
02663 if ( $oDeliveryPrice = $this->_aCosts['oxdelivery'] ) {
02664 $dPrice += $oDeliveryPrice->getBruttoPrice();
02665 }
02666
02667 return $dPrice;
02668 }
02669
02670
02676 public function _getDiscountedProductsSum()
02677 {
02678 if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02679 $dPrice = $oProductsPrice->getSum( $this->isCalculationModeNetto() );
02680 }
02681
02682
02683 if ( $oPrice = $this->getTotalDiscount() ) {
02684 $dPrice -= $oPrice->getPrice();
02685 }
02686
02687 if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02688 $dPrice -= $oVoucherPrice->getPrice();
02689 }
02690
02691 return $dPrice;
02692 }
02693
02699 public function getDiscountedProductsBruttoPrice()
02700 {
02701 if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02702 $dPrice = $oProductsPrice->getBruttoSum();
02703 }
02704
02705
02706 if ( $oPrice = $this->getTotalDiscount() ) {
02707 $dPrice -= $oPrice->getBruttoPrice();
02708 }
02709
02710 if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02711 $dPrice -= $oVoucherPrice->getBruttoPrice();
02712 }
02713
02714 return $dPrice;
02715 }
02716
02722 public function isBelowMinOrderPrice()
02723 {
02724 $blIsBelowMinOrderPrice = false;
02725 $sConfValue = $this->getConfig()->getConfigParam( 'iMinOrderPrice' );
02726 if ( is_numeric($sConfValue) && $this->getProductsCount() ) {
02727 $dMinOrderPrice = oxPrice::getPriceInActCurrency( ( double ) $sConfValue );
02728 $dNotDiscountedProductPrice = 0;
02729 if ( $oPrice = $this->getNotDiscountProductsPrice() ) {
02730 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02731 }
02732 $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02733 }
02734
02735 return $blIsBelowMinOrderPrice;
02736
02737 }
02738
02747 public function getArtStockInBasket( $sArtId, $sExpiredArtId = null )
02748 {
02749 $dArtStock = 0;
02750 foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
02751 if ( $oOrderArticle && ( $sExpiredArtId == null || $sExpiredArtId != $sItemKey ) ) {
02752 if ( $oOrderArticle->getArticle( true )->getId() == $sArtId ) {
02753 $dArtStock += $oOrderArticle->getAmount();
02754 }
02755 }
02756 }
02757
02758 return $dArtStock;
02759 }
02760
02768 public function canAddProductToBasket( $sProductId )
02769 {
02770 $blCanAdd = null;
02771
02772
02773 if ( $this->_sBasketCategoryId === null ) {
02774 $oCat = null;
02775
02776
02777 if ( $oView = $this->getConfig()->getActiveView() ) {
02778 if ( $oCat = $oView->getActiveCategory() ) {
02779 if ( !$this->_isProductInRootCategory( $sProductId, $oCat->oxcategories__oxrootid->value ) ) {
02780 $oCat = null;
02781 } else {
02782 $blCanAdd = true;
02783 }
02784 }
02785 }
02786
02787
02788 if ( !$oCat ) {
02789 $oProduct = oxNew( "oxarticle" );
02790 if ( $oProduct->load( $sProductId ) ) {
02791 $oCat = $oProduct->getCategory();
02792 }
02793 }
02794
02795
02796 if ( $oCat ) {
02797 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02798 }
02799 }
02800
02801
02802 if ( $blCanAdd === null ) {
02803 $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory( $sProductId, $this->getBasketRootCatId() ) : true;
02804 }
02805
02806 return $blCanAdd;
02807 }
02808
02817 protected function _isProductInRootCategory( $sProductId, $sRootCatId )
02818 {
02819 $sO2CTable = getViewName( 'oxobject2category' );
02820 $sCatTable = getViewName( 'oxcategories' );
02821
02822 $oDb = oxDb::getDb();
02823 $sParentId = $oDb->getOne( "select oxparentid from oxarticles where oxid = ".$oDb->quote( $sProductId ) );
02824 $sProductId = $sParentId ? $sParentId : $sProductId;
02825
02826 $sQ = "select 1 from {$sO2CTable}
02827 left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02828 where {$sO2CTable}.oxobjectid = ".$oDb->quote( $sProductId )." and
02829 {$sCatTable}.oxrootid = ".$oDb->quote( $sRootCatId );
02830
02831 return (bool) $oDb->getOne( $sQ );
02832 }
02833
02841 public function setBasketRootCatId($sRoot)
02842 {
02843 $this->_sBasketCategoryId = $sRoot;
02844 }
02845
02851 public function getBasketRootCatId()
02852 {
02853 return $this->_sBasketCategoryId;
02854 }
02855
02863 public function setCatChangeWarningState( $blShow )
02864 {
02865 $this->_blShowCatChangeWarning = $blShow;
02866 }
02867
02873 public function showCatChangeWarning()
02874 {
02875 return $this->_blShowCatChangeWarning;
02876 }
02877
02885 public function setTsProductId( $sProductId )
02886 {
02887 $this->_sTsProductId = $sProductId;
02888 }
02889
02895 public function getTsProductId()
02896 {
02897 return $this->_sTsProductId;
02898 }
02899
02905 public function getFTsProtectionCosts()
02906 {
02907 $oProtectionCost = $this->getCosts( 'oxtsprotection' );
02908 if ( $oProtectionCost && $oProtectionCost->getBruttoPrice() ) {
02909 return oxRegistry::getLang()->formatCurrency( $oProtectionCost->getBruttoPrice(), $this->getBasketCurrency() );
02910 }
02911 return false;
02912 }
02913
02919 public function getTsProtectionVatPercent()
02920 {
02921 return $this->getCosts( 'oxtsprotection' )->getVat();
02922 }
02923
02929 public function getTsProtectionVat()
02930 {
02931 $dProtectionVAT = $this->getCosts( 'oxtsprotection' )->getVatValue();
02932
02933 if ( $dProtectionVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02934 return oxRegistry::getLang()->formatCurrency( $dProtectionVAT, $this->getBasketCurrency() );
02935 }
02936 return false;
02937 }
02938
02944 public function getTsProtectionNet()
02945 {
02946
02947 if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02948 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxtsprotection' )->getNettoPrice(), $this->getBasketCurrency() );
02949 }
02950 return false;
02951 }
02952
02958 public function getTsProtectionCosts()
02959 {
02960 $oProtection = $this->getCosts( 'oxtsprotection' );
02961 if ( $oProtection ) {
02962 return $oProtection->getBruttoPrice();
02963 }
02964 return false;
02965 }
02966
02972 public function getNotDiscountProductsPrice()
02973 {
02974 return $this->_oNotDiscountedProductsPriceList;
02975 }
02976
02990 protected function _addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId )
02991 {
02992 if ( !$blOverride ) {
02993 $this->_blNewITemAdded = null;
02994 oxSession::setVar( "blAddedNewItem", true );
02995 }
02996 }
02997
03003 public function __wakeUp()
03004 {
03005 $this->_blNewITemAdded = null;
03006 $this->_isCalculationModeNetto = null;
03007 }
03008
03014 public function isNewItemAdded()
03015 {
03016 if ( $this->_blNewITemAdded == null ) {
03017 $this->_blNewITemAdded = (bool) oxSession::getVar( "blAddedNewItem" );
03018 oxSession::deleteVar( "blAddedNewItem" );
03019 }
03020 return $this->_blNewITemAdded;
03021 }
03022
03028 public function hasDownloadableProducts()
03029 {
03030 $this->_blDownloadableProducts = false;
03031 foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
03032 if ( $oOrderArticle->getArticle( false ) && $oOrderArticle->getArticle( false )->isDownloadable() ) {
03033 $this->_blDownloadableProducts = true;
03034 break;
03035 }
03036 }
03037
03038 return $this->_blDownloadableProducts;
03039 }
03040
03041 }