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 $sItemId = $oOrderArticle->getId();
00484
00485
00486 $this->_aBasketContents[$sItemId] = oxNew( 'oxbasketitem' );
00487 $this->_aBasketContents[$sItemId]->initFromOrderArticle( $oOrderArticle );
00488 $this->_aBasketContents[$sItemId]->setWrapping( $oOrderArticle->oxorderarticles__oxwrapid->value );
00489 $this->_aBasketContents[$sItemId]->setBundle( $oOrderArticle->isBundle() );
00490
00491
00492 $this->onUpdate();
00493
00494 return $this->_aBasketContents[$sItemId];
00495 } elseif ( $oOrderArticle->isBundle() ) {
00496
00497 $oOrderArticle->delete();
00498 }
00499 }
00500
00508 public function setStockCheckMode( $blCheck )
00509 {
00510 $this->_blCheckStock = $blCheck;
00511 }
00512
00518 public function getStockCheckMode()
00519 {
00520 return $this->_blCheckStock;
00521 }
00522
00535 public function getItemKey( $sProductId, $aSel = null, $aPersParam = null, $blBundle = false, $sAdditionalParam = '' )
00536 {
00537 $aSel = ( $aSel != null) ? $aSel : array (0=>'0');
00538
00539 $sItemKey = md5( $sProductId.'|'.serialize( $aSel ).'|'.serialize( $aPersParam ).'|'.( int ) $blBundle . '|' . serialize( $sAdditionalParam ) );
00540
00541 return $sItemKey;
00542 }
00543
00544
00552 public function removeItem( $sItemKey )
00553 {
00554 if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
00555 if (isset($this->_aBasketContents[$sItemKey])) {
00556 $sArticleId = $this->_aBasketContents[$sItemKey]->getProductId();
00557 if ($sArticleId) {
00558 $this->getSession()
00559 ->getBasketReservations()
00560 ->discardArticleReservation($sArticleId);
00561 }
00562 }
00563 }
00564 unset( $this->_aBasketContents[$sItemKey] );
00565
00566
00567 if ( !count($this->_aBasketContents) && $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' ) ) {
00568 $this->setBasketRootCatId(null);
00569 }
00570 }
00571
00577 protected function _clearBundles()
00578 {
00579 reset( $this->_aBasketContents );
00580 while ( list( $sItemKey, $oBasketItem ) = each( $this->_aBasketContents ) ) {
00581 if ( $oBasketItem->isBundle() ) {
00582 $this->removeItem( $sItemKey );
00583 }
00584 }
00585 }
00586
00594 protected function _getArticleBundles( $oBasketItem )
00595 {
00596 $aBundles = array();
00597
00598 if ( $oBasketItem->isBundle() ) {
00599 return $aBundles;
00600 }
00601
00602 $oArticle = $oBasketItem->getArticle( true );
00603 if ( $oArticle && $oArticle->oxarticles__oxbundleid->value ) {
00604 $aBundles[$oArticle->oxarticles__oxbundleid->value] = 1;
00605 }
00606
00607 return $aBundles;
00608 }
00609
00618 protected function _getItemBundles( $oBasketItem, $aBundles = array() )
00619 {
00620 if ( $oBasketItem->isBundle() ) {
00621 return array();
00622 }
00623
00624
00625 if ( $oArticle = $oBasketItem->getArticle() ) {
00626 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketItemBundleDiscounts( $oArticle, $this, $this->getBasketUser() );
00627
00628 foreach ( $aDiscounts as $oDiscount ) {
00629
00630 $iAmnt = $oDiscount->getBundleAmount( $oBasketItem->getAmount() );
00631 if ( $iAmnt ) {
00632
00633 if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00634 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00635 }
00636
00637 if ($oDiscount->oxdiscount__oxitmmultiple->value) {
00638 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $iAmnt;
00639 } else {
00640 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = $iAmnt;
00641 }
00642 }
00643 }
00644 }
00645
00646 return $aBundles;
00647 }
00648
00656 protected function _getBasketBundles( $aBundles = array() )
00657 {
00658 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketBundleDiscounts( $this, $this->getBasketUser() );
00659
00660
00661 $dAmount = 0;
00662 foreach ( $this->_aBasketContents as $oBasketItem ) {
00663 if ( !( $oBasketItem->isBundle() || $oBasketItem->isDiscountArticle() ) ) {
00664 $dAmount += $oBasketItem->getAmount();
00665 }
00666 }
00667
00668 foreach ( $aDiscounts as $oDiscount ) {
00669 if ($oDiscount->oxdiscount__oxitmartid->value) {
00670 if ( !isset( $aBundles[$oDiscount->oxdiscount__oxitmartid->value] ) ) {
00671 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00672 }
00673
00674 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $oDiscount->getBundleAmount( $dAmount );
00675 }
00676 }
00677
00678 return $aBundles;
00679 }
00680
00687 protected function _addBundles()
00688 {
00689 $aBundles = array();
00690
00691 foreach ( $this->_aBasketContents as $key => $oBasketItem ) {
00692 try {
00693
00694 if ( !$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle() ) {
00695 $aBundles = $this->_getItemBundles( $oBasketItem, $aBundles );
00696 } else {
00697 continue;
00698 }
00699
00700
00701 $aArtBundles = $this->_getArticleBundles( $oBasketItem );
00702
00703
00704 $this->_addBundlesToBasket( $aArtBundles );
00705 } catch ( oxNoArticleException $oEx ) {
00706 $this->removeItem( $key );
00707 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00708 } catch( oxArticleInputException $oEx ) {
00709 $this->removeItem( $key );
00710 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00711 }
00712 }
00713
00714
00715 $aBundles = $this->_getBasketBundles( $aBundles );
00716
00717
00718 if ( $aBundles ) {
00719 $this->_addBundlesToBasket( $aBundles );
00720 }
00721 }
00722
00730 protected function _addBundlesToBasket( $aBundles )
00731 {
00732 foreach ( $aBundles as $sBundleId => $dAmount ) {
00733 if ( $dAmount ) {
00734 try {
00735 if ( $oBundleItem = $this->addToBasket( $sBundleId, $dAmount, null, null, false, true ) ) {
00736 $oBundleItem->setAsDiscountArticle( true );
00737 }
00738 } catch(oxArticleException $oEx) {
00739
00740 }
00741 }
00742 }
00743
00744 }
00745
00751 protected function _calcItemsPrice()
00752 {
00753
00754 $this->setSkipDiscounts( false );
00755 $this->_iProductsCnt = 0;
00756 $this->_dItemsCnt = 0;
00757 $this->_dWeight = 0;
00758
00759 $this->_oProductsPriceList = oxNew( 'oxpricelist' );
00760 $this->_oDiscountProductsPriceList = oxNew( 'oxpricelist' );
00761 $this->_oNotDiscountedProductsPriceList = oxNew( 'oxpricelist' );
00762
00763 $oDiscountList = oxRegistry::get("oxDiscountList");
00764
00765 foreach ( $this->_aBasketContents as $oBasketItem ) {
00766 $this->_iProductsCnt++;
00767 $this->_dItemsCnt += $oBasketItem->getAmount();
00768 $this->_dWeight += $oBasketItem->getWeight();
00769
00770 if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle( true ) ) ) {
00771
00772 $oBasketPrice = $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $this );
00773 $oBasketItem->setRegularUnitPrice( clone $oBasketPrice );
00774
00775 if ( !$oArticle->skipDiscounts() && $this->canCalcDiscounts() ) {
00776
00777 $aDiscounts = $oDiscountList->getBasketItemDiscounts( $oArticle, $this, $this->getBasketUser() );
00778 reset( $aDiscounts );
00779 foreach ( $aDiscounts as $oDiscount ) {
00780 $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
00781 }
00782 $oBasketPrice->calculateDiscount();
00783 } else {
00784 $oBasketItem->setSkipDiscounts( true );
00785 $this->setSkipDiscounts( true );
00786 }
00787
00788 $oBasketItem->setPrice( $oBasketPrice );
00789 $this->_oProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00790
00791
00792 if ( !$oArticle->skipDiscounts() ) {
00793
00794 $this->_oDiscountProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00795 } else {
00796 $this->_oNotDiscountedProductsPriceList->addToPriceList( $oBasketItem->getPrice() );
00797 $oBasketItem->setSkipDiscounts( true );
00798 $this->setSkipDiscounts( true );
00799 }
00800 } elseif ( $oBasketItem->isBundle() ) {
00801
00802 $oPrice = oxNew( "oxprice");
00803 $oBasketItem->setPrice( $oPrice );
00804 }
00805 }
00806 }
00807
00815 public function setDiscountCalcMode( $blCalcDiscounts )
00816 {
00817 $this->_blCalcDiscounts = $blCalcDiscounts;
00818 }
00819
00825 public function canCalcDiscounts()
00826 {
00827 return $this->_blCalcDiscounts;
00828 }
00829
00839 protected function _mergeDiscounts( $aDiscounts, $aItemDiscounts)
00840 {
00841 foreach ( $aItemDiscounts as $sKey => $oDiscount ) {
00842
00843 if ( array_key_exists ($sKey, $aDiscounts) ) {
00844 $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
00845 } else {
00846 $aDiscounts[$sKey] = $oDiscount;
00847 }
00848 }
00849 return $aDiscounts;
00850 }
00851
00857 protected function _calcDeliveryCost()
00858 {
00859 if ( $this->_oDeliveryPrice !== null ) {
00860 return $this->_oDeliveryPrice;
00861 }
00862 $myConfig = $this->getConfig();
00863 $oDeliveryPrice = oxNew( 'oxprice' );
00864
00865 if ( $this->getConfig()->getConfigParam( 'blDeliveryVatOnTop' ) ) {
00866 $oDeliveryPrice->setNettoPriceMode();
00867 } else {
00868 $oDeliveryPrice->setBruttoPriceMode();
00869 }
00870
00871
00872 $oUser = $this->getBasketUser();
00873
00874 if ( !$oUser && !$myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) {
00875 return $oDeliveryPrice;
00876 }
00877
00878
00879
00880
00881 $fDelVATPercent = 0;
00882 $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00883 $oDeliveryPrice->setVat( $fDelVATPercent );
00884
00885
00886 if ( $myConfig->getConfigParam('bl_perfLoadDelivery') ) {
00887 $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList( $this,
00888 $oUser,
00889 $this->_findDelivCountry(),
00890 $this->getShippingId()
00891 );
00892
00893 if ( count( $aDeliveryList ) > 0 ) {
00894 foreach ( $aDeliveryList as $oDelivery ) {
00895
00896 if ( $myConfig->getConfigParam( 'iDebug' ) == 5 ) {
00897 echo( "DelCost : ".$oDelivery->oxdelivery__oxtitle->value."<br>" );
00898 }
00899 $oDeliveryPrice->addPrice( $oDelivery->getDeliveryPrice( $fDelVATPercent ) );
00900 }
00901 }
00902 }
00903
00904 return $oDeliveryPrice;
00905 }
00906
00912 public function getBasketUser()
00913 {
00914 if ( $this->_oUser == null ) {
00915 return $this->getUser();
00916 }
00917
00918 return $this->_oUser;
00919 }
00920
00928 public function setBasketUser( $oUser )
00929 {
00930 $this->_oUser = $oUser;
00931 }
00932
00933
00939 public function getMostUsedVatPercent()
00940 {
00941 if ( $this->_oProductsPriceList ) {
00942 return $this->_oProductsPriceList->getMostUsedVatPercent();
00943 }
00944 }
00945
00951 public function getAdditionalServicesVatPercent()
00952 {
00953 if ( $this->_oProductsPriceList ) {
00954 if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional') {
00955 return $this->_oProductsPriceList->getProportionalVatPercent();
00956 } else {
00957 return $this->_oProductsPriceList->getMostUsedVatPercent();
00958 }
00959 }
00960 }
00961
00967 public function isProportionalCalculationOn()
00968 {
00969 if ( $this->getConfig()->getConfigParam( 'sAdditionalServVATCalcMethod') == 'proportional' ) {
00970 return true;
00971 }
00972 return false;
00973 }
00974
00975
00976
00983 protected function _calcTotalPrice()
00984 {
00985
00986 $dprice = $this->_dBruttoSum;
00987 $this->_oPrice = oxNew( 'oxPrice' );
00988 $this->_oPrice->setBruttoPriceMode();
00989 $this->_oPrice->setPrice( $dprice );
00990
00991
00992 if ( $dprice && !$this->isCalculationModeNetto() ) {
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 $this->_oPrice->subtract( $this->_oTotalDiscount->getBruttoPrice() );
01006
01007
01008 if ($oVoucherDisc = $this->getVoucherDiscount()) {
01009 $this->_oPrice->subtract( $oVoucherDisc->getBruttoPrice() );
01010 }
01011 }
01012
01013
01014 if ( isset( $this->_aCosts['oxdelivery'] ) ) {
01015 $this->_oPrice->add( $this->_aCosts['oxdelivery']->getBruttoPrice() );
01016 }
01017
01018
01019 if ( isset( $this->_aCosts['oxwrapping'] ) ) {
01020 $this->_oPrice->add( $this->_aCosts['oxwrapping']->getBruttoPrice() );
01021 }
01022 if ( isset( $this->_aCosts['oxgiftcard'] ) ) {
01023 $this->_oPrice->add( $this->_aCosts['oxgiftcard']->getBruttoPrice() );
01024 }
01025
01026
01027 if ( isset( $this->_aCosts['oxpayment'] ) ) {
01028 $this->_oPrice->add( $this->_aCosts['oxpayment']->getBruttoPrice() );
01029 }
01030
01031
01032 if ( isset( $this->_aCosts['oxtsprotection'] ) ) {
01033 $this->_oPrice->add( $this->_aCosts['oxtsprotection']->getBruttoPrice() );
01034 }
01035
01036 }
01037
01045 public function setVoucherDiscount( $dDiscount )
01046 {
01047 $this->_oVoucherDiscount = oxNew( 'oxPrice' );
01048 $this->_oVoucherDiscount->setBruttoPriceMode();
01049 $this->_oVoucherDiscount->add( $dDiscount );
01050 }
01051
01057 protected function _calcVoucherDiscount()
01058 {
01059 if ( $this->getConfig()->getConfigParam( 'bl_showVouchers' ) && ($this->_oVoucherDiscount === null || ( $this->_blUpdateNeeded && !$this->isAdmin() ) ) ) {
01060
01061 $this->_oVoucherDiscount = $this->_getPriceObject();
01062
01063
01064 $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() ) - $this->_oTotalDiscount->getPrice();
01065
01066
01067 if ( count( $this->_aVouchers ) ) {
01068 $oLang = oxRegistry::getLang();
01069 foreach ( $this->_aVouchers as $sVoucherId => $oStdVoucher ) {
01070 $oVoucher = oxNew( 'oxvoucher' );
01071 try {
01072 $oVoucher->load( $oStdVoucher->sVoucherId );
01073
01074 if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01075 $oVoucher->checkBasketVoucherAvailability( $this->_aVouchers, $dPrice );
01076 $oVoucher->checkUserAvailability( $this->getBasketUser() );
01077 }
01078
01079
01080 $dVoucherdiscount = $oVoucher->getDiscountValue( $dPrice );
01081
01082 if ( $dVoucherdiscount > 0 ) {
01083
01084 if ( $oVoucher->getDiscountType() == 'absolute' ) {
01085 $dVatPart = ( $dPrice - $dVoucherdiscount ) / $dPrice * 100;
01086 } else {
01087 $dVatPart = 100 - $oVoucher->getDiscount();
01088 }
01089
01090 if ( !$this->_aDiscountedVats ) {
01091 if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01092 $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01093 }
01094 }
01095
01096
01097 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01098 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01099 }
01100 }
01101
01102
01103 $this->_oVoucherDiscount->add( $dVoucherdiscount );
01104
01105
01106 $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency( $dVoucherdiscount, $this->getBasketCurrency() );
01107 $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01108
01109
01110 $dPrice = $dPrice - $dVoucherdiscount;
01111
01112
01113
01114 } catch ( oxVoucherException $oEx ) {
01115
01116
01117 $oVoucher->unMarkAsReserved();
01118 unset( $this->_aVouchers[$sVoucherId] );
01119
01120
01121 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01122 }
01123 }
01124 }
01125 }
01126 }
01127
01134 protected function _applyDiscounts()
01135 {
01136 $dBruttoPrice = 0;
01137
01138
01139 $dDiscountedBruttoPrice = $this->_getDiscountedProductsSum();
01140 $oTotalDiscount = $this->getTotalDiscount();
01141 $oVoucherDiscount = $this->getVoucherDiscount();
01142
01143 $oUtils = oxRegistry::getUtils();
01144 $dVatSum = 0;
01145 foreach ( $this->_aDiscountedVats as $dVat ) {
01146 $dVatSum += $oUtils->fRound( $dVat, $this->_oCurrency);
01147 }
01148
01149 $oNotDiscounted = $this->getNotDiscountProductsPrice();
01150
01151 if ( $this->isCalculationModeNetto() ) {
01152
01153 $this->setNettoSum($this->getProductsPrice()->getSum());
01154 $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedBruttoPrice + $dVatSum);
01155 } else {
01156
01157 $this->setNettoSum( $oNotDiscounted->getSum() + $dDiscountedBruttoPrice - $dVatSum );
01158 $this->setBruttoSum( $this->getProductsPrice()->getSum(false) );
01159 }
01160 }
01166 public function isPriceViewModeNetto()
01167 {
01168 $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
01169 $oUser = $this->getBasketUser();
01170 if ( $oUser ) {
01171 $blResult = $oUser->isPriceViewModeNetto();
01172 }
01173
01174 return $blResult;
01175 }
01176
01182 protected function _getPriceObject()
01183 {
01184 $oPrice = oxNew( 'oxPrice' );
01185
01186 if ( $this->isCalculationModeNetto() ) {
01187 $oPrice->setNettoPriceMode();
01188 } else {
01189 $oPrice->setBruttoPriceMode();
01190 }
01191
01192 return $oPrice;
01193 }
01194
01200 protected function _calcBasketDiscount()
01201 {
01202
01203 $this->_aDiscounts = array();
01204
01205
01206 $dOldprice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01207
01208
01209 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts( $this, $this->getBasketUser() );
01210 if ( $oPriceList = $this->getDiscountProductsPrice() ) {
01211 $this->_aDiscountedVats = $oPriceList->getVatInfo( $this->isCalculationModeNetto() );
01212 }
01213
01214 foreach ( $aDiscounts as $oDiscount ) {
01215
01216
01217 $oStdDiscount = $oDiscount->getSimpleDiscount();
01218
01219
01220 if ( $oDiscount->oxdiscount__oxaddsumtype->value == 'itm' ) {
01221 continue;
01222 }
01223
01224
01225 $oStdDiscount->dDiscount = $oDiscount->getAbsValue( $dOldprice );
01226
01227
01228
01229 $dVatPart = 100 - $oDiscount->getPercentage( $dOldprice );
01230
01231
01232 if ( $dOldprice < $oStdDiscount->dDiscount ) {
01233 $oStdDiscount->dDiscount = $dOldprice;
01234 $dVatPart = 0;
01235 }
01236
01237
01238 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
01239 $this->_aDiscountedVats[$sKey] = oxPrice::percent( $dVat, $dVatPart);
01240 }
01241
01242
01243 if ($oStdDiscount->dDiscount != 0) {
01244 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01245
01246 $dOldprice = $dOldprice - $oStdDiscount->dDiscount;
01247 }
01248 }
01249 }
01250
01256 protected function _calcBasketTotalDiscount()
01257 {
01258 if ( $this->_oTotalDiscount === null || ( !$this->isAdmin() ) ) {
01259
01260 $this->_oTotalDiscount = $this->_getPriceObject();
01261
01262 if ( is_array($this->_aDiscounts) ) {
01263 foreach ( $this->_aDiscounts as $oDiscount ) {
01264
01265
01266 if ( $oDiscount->sType == 'itm' ) {
01267 continue;
01268 }
01269
01270
01271 $this->_oTotalDiscount->add( $oDiscount->dDiscount );
01272 }
01273 }
01274 }
01275 }
01276
01285 protected function _calcBasketWrapping()
01286 {
01287 $oWrappingPrices = oxNew( 'oxPriceList' );
01288
01289 foreach ( $this->_aBasketContents as $oBasketItem ) {
01290
01291 if ( ( $oWrapping = $oBasketItem->getWrapping() ) ) {
01292
01293 $oWrappingPrice = $oWrapping->getWrappingPrice( $oBasketItem->getAmount() );
01294 $oWrappingPrice->setVat( $oBasketItem->getPrice()->getVat() );
01295
01296 $oWrappingPrices->addToPriceList( $oWrappingPrice );
01297 }
01298 }
01299
01300 if ( $oWrappingPrices->getCount() ) {
01301 $oWrappingCost = oxNew( 'oxPrice' );
01302 $oWrappingCost = $oWrappingPrices->calculateToPrice();
01303 }
01304
01305 return $oWrappingCost;
01306 }
01307
01316 protected function _calcBasketGiftCard()
01317 {
01318 $oGiftCardPrice = oxNew( 'oxPrice' );
01319
01320 if ( $this->getConfig()->getConfigParam( 'blWrappingVatOnTop' ) ) {
01321 $oGiftCardPrice->setNettoPriceMode();
01322 } else {
01323 $oGiftCardPrice->setBruttoPriceMode();
01324 }
01325
01326 $dVATPercent = $this->getAdditionalServicesVatPercent();
01327
01328 $oGiftCardPrice->setVat( $dVATPercent );
01329
01330
01331 if ( ( $oCard = $this->getCard() ) ) {
01332 if ($dVATPercent !== null) {
01333 $oCard->setWrappingVat($dVATPercent);
01334 }
01335 $oGiftCardPrice->addPrice( $oCard->getWrappingPrice() );
01336 }
01337
01338 return $oGiftCardPrice;
01339 }
01340
01347 protected function _calcPaymentCost()
01348 {
01349
01350 $oPaymentPrice = oxNew( 'oxPrice' );
01351
01352
01353 if ( ( $this->_sPaymentId = $this->getPaymentId() ) ) {
01354
01355 $oPayment = oxNew( 'oxpayment' );
01356 $oPayment->load( $this->_sPaymentId );
01357
01358 $oPayment->calculate( $this );
01359 $oPaymentPrice = $oPayment->getPrice();
01360 }
01361
01362 return $oPaymentPrice;
01363 }
01364
01371 protected function _calcTsProtectionCost()
01372 {
01373 if ( ( $this->getTsProductId() ) ) {
01374 $oTsProtection = oxNew('oxtsprotection');
01375 $oTsProduct = $oTsProtection->getTsProduct( $this->getTsProductId() );
01376 $oProtectionPrice = $oTsProduct->getPrice();
01377 $oProtectionPrice->setVat( $this->getAdditionalServicesVatPercent() );
01378 } else {
01379 $oProtectionPrice = oxNew( 'oxPrice' );
01380 }
01381
01382 return $oProtectionPrice;
01383 }
01384
01393 public function setCost( $sCostName, $oPrice = null )
01394 {
01395 $this->_aCosts[$sCostName] = $oPrice;
01396 }
01397
01406 public function calculateBasket( $blForceUpdate = false )
01407 {
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422 if ( !$this->isEnabled() ) {
01423 return;
01424 }
01425
01426 if ( $blForceUpdate ) {
01427 $this->onUpdate();
01428 }
01429
01430 if ( !($this->_blUpdateNeeded || $blForceUpdate) ) {
01431 return;
01432 }
01433
01434 $this->_aCosts = array();
01435
01436
01437 $this->_save();
01438
01439
01440 $this->_clearBundles();
01441
01442
01443 $this->_addBundles();
01444
01445
01446 if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01447 $this->getSession()->getBasketReservations()->reserveBasket($this);
01448 }
01449
01450
01451 $this->_calcItemsPrice();
01452
01453
01454 $this->_calcBasketDiscount();
01455
01456
01457 $this->_calcBasketTotalDiscount();
01458
01459
01460 $this->_calcVoucherDiscount();
01461
01462
01463 $this->_applyDiscounts();
01464
01465
01466
01467 $this->setCost( 'oxdelivery', $this->_calcDeliveryCost() );
01468
01469
01470 $this->setCost( 'oxwrapping', $this->_calcBasketWrapping() );
01471
01472 $this->setCost( 'oxgiftcard', $this->_calcBasketGiftCard() );
01473
01474
01475 $this->setCost( 'oxpayment', $this->_calcPaymentCost() );
01476
01477
01478 $this->setCost( 'oxtsprotection', $this->_calcTsProtectionCost() );
01479
01480
01481 $this->_calcTotalPrice();
01482
01483
01484 $this->formatDiscount();
01485
01486
01487 $this->afterUpdate();
01488 }
01489
01495 public function onUpdate()
01496 {
01497 $this->_blUpdateNeeded = true;
01498 }
01499
01505 public function afterUpdate()
01506 {
01507 $this->_blUpdateNeeded = false;
01508 }
01509
01517 public function getBasketSummary()
01518 {
01519 if ( $this->_blUpdateNeeded || $this->_aBasketSummary === null ) {
01520 $this->_aBasketSummary = new stdclass();
01521 $this->_aBasketSummary->aArticles = array();
01522 $this->_aBasketSummary->aCategories = array();
01523 $this->_aBasketSummary->iArticleCount = 0;
01524 $this->_aBasketSummary->dArticlePrice = 0;
01525 $this->_aBasketSummary->dArticleDiscountablePrice = 0;
01526 }
01527
01528 if ( !$this->isEnabled() ) {
01529 return $this->_aBasketSummary;
01530 }
01531
01532 $myConfig = $this->getConfig();
01533 foreach ( $this->_aBasketContents as $oBasketItem ) {
01534 if ( !$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false) ) {
01535 $aCatIds = $oArticle->getCategoryIds();
01536
01537 $dPrice = 0;
01538 $dDiscountablePrice = 0;
01539 if ( ( $oPrice = $oArticle->getPrice( $oBasketItem->getAmount() ) ) ) {
01540 $dPrice = $oPrice->getPrice();
01541 if ( !$oArticle->skipDiscounts() ) {
01542 $dDiscountablePrice = $dPrice;
01543 }
01544 }
01545
01546 foreach ( $aCatIds as $sCatId ) {
01547 if ( !isset( $this->_aBasketSummary->aCategories[$sCatId] ) ) {
01548 $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
01549 }
01550
01551 $this->_aBasketSummary->aCategories[$sCatId]->dPrice += $dPrice * $oBasketItem->getAmount();
01552 $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01553 $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
01554 $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
01555 }
01556
01557
01558 if ( ($sParentId = $oArticle->getProductParentId()) && $myConfig->getConfigParam( 'blVariantParentBuyable' ) ) {
01559 if ( !isset( $this->_aBasketSummary->aArticles[$sParentId] ) ) {
01560 $this->_aBasketSummary->aArticles[$sParentId] = 0;
01561 }
01562 $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
01563 }
01564
01565 if ( !isset( $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] ) ) {
01566 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
01567 }
01568
01569 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
01570 $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
01571 $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
01572 $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01573 }
01574 }
01575 return $this->_aBasketSummary;
01576 }
01577
01589 public function addVoucher( $sVoucherId )
01590 {
01591
01592
01593 $dPrice = 0;
01594 if ( $this->_oDiscountProductsPriceList ) {
01595 $dPrice = $this->_oDiscountProductsPriceList->getSum( $this->isCalculationModeNetto() );
01596 }
01597
01598 try {
01599
01600 $oVoucher = oxNew( 'oxvoucher' );
01601
01602 if ( !$this->_blSkipVouchersAvailabilityChecking ) {
01603 $oVoucher->getVoucherByNr( $sVoucherId, $this->_aVouchers, true );
01604 $oVoucher->checkVoucherAvailability( $this->_aVouchers, $dPrice );
01605 $oVoucher->checkUserAvailability( $this->getBasketUser() );
01606 $oVoucher->markAsReserved();
01607 } else {
01608 $oVoucher->load( $sVoucherId );
01609 }
01610
01611
01612 $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
01613 } catch ( oxVoucherException $oEx ) {
01614
01615
01616 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false, true );
01617 }
01618
01619 $this->onUpdate();
01620 }
01621
01629 public function removeVoucher( $sVoucherId )
01630 {
01631
01632 if ( isset( $this->_aVouchers[$sVoucherId] ) ) {
01633
01634 $oVoucher = oxNew( 'oxvoucher' );
01635 $oVoucher->load( $sVoucherId );
01636
01637 $oVoucher->unMarkAsReserved();
01638
01639
01640 unset( $this->_aVouchers[$sVoucherId] );
01641 $this->onUpdate();
01642 }
01643
01644 }
01645
01651 public function resetUserInfo()
01652 {
01653 $this->setPayment( null );
01654 $this->setShipping( null );
01655 }
01656
01662 protected function formatDiscount()
01663 {
01664
01665
01666 $this->aDiscounts = $this->getDiscounts();
01667 if ( count($this->aDiscounts) > 0 ) {
01668 $oLang = oxRegistry::getLang();
01669 foreach ($this->aDiscounts as $oDiscount) {
01670 $oDiscount->fDiscount = $oLang->formatCurrency( $oDiscount->dDiscount, $this->getBasketCurrency() );
01671 }
01672 }
01673 }
01674
01675
01681 protected function _canSaveBasket()
01682 {
01683 $blCanSave = !$this->getConfig()->getConfigParam( 'blPerfNoBasketSaving' );
01684 return $blCanSave;
01685 }
01686
01692 public function load()
01693 {
01694 $oUser = $this->getBasketUser();
01695 if ( !$oUser ) {
01696 return;
01697 }
01698
01699 $oBasket = $oUser->getBasket( 'savedbasket' );
01700
01701
01702 $aSavedItems = $oBasket->getItems();
01703 foreach ( $aSavedItems as $oItem ) {
01704 try {
01705 $oSelList = $oItem->getSelList();
01706
01707 $this->addToBasket( $oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true );
01708 } catch( oxArticleException $oEx ) {
01709
01710 }
01711 }
01712 }
01713
01719 protected function _save()
01720 {
01721 if ( $this->_canSaveBasket() ) {
01722
01723 if ( $oUser = $this->getBasketUser() ) {
01724
01725
01726 $oSavedBasket = $oUser->getBasket( 'savedbasket' );
01727 $oSavedBasket->delete();
01728
01729
01730 foreach ( $this->_aBasketContents as $oBasketItem ) {
01731
01732 if ( !$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle() ) {
01733 $oSavedBasket->addItemToBasket( $oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams() );
01734 }
01735 }
01736 }
01737 }
01738 }
01739
01751
01752
01753
01754
01755
01756
01757
01758
01759
01767 protected function _deleteSavedBasket()
01768 {
01769
01770 if ( $oUser = $this->getBasketUser() ) {
01771 $oUser->getBasket( 'savedbasket' )->delete();
01772 }
01773
01774
01775 if ( $this->getConfig()->getConfigParam( 'blBasketExcludeEnabled' )) {
01776 $this->setBasketRootCatId(null);
01777 }
01778 }
01779
01785 protected function _findDelivCountry()
01786 {
01787 $myConfig = $this->getConfig();
01788 $oUser = $this->getBasketUser();
01789
01790 $sDelivCountry = null;
01791
01792 if ( !$oUser ) {
01793
01794 $aHomeCountry = $myConfig->getConfigParam( 'aHomeCountry' );
01795 if ( $myConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) && is_array( $aHomeCountry ) ) {
01796 $sDelivCountry = current( $aHomeCountry );
01797 }
01798 } else {
01799
01800
01801 if ( $sCountryId = $myConfig->getGlobalParameter( 'delcountryid' ) ) {
01802 $sDelivCountry = $sCountryId;
01803 } elseif ( $sAddressId = oxSession::getVar( 'deladrid' ) ) {
01804
01805 $oDelAdress = oxNew( 'oxaddress' );
01806 if ( $oDelAdress->load( $sAddressId ) ) {
01807 $sDelivCountry = $oDelAdress->oxaddress__oxcountryid->value;
01808 }
01809 }
01810
01811
01812 if ( !$sDelivCountry ) {
01813 $sDelivCountry = $oUser->oxuser__oxcountryid->value;
01814 }
01815 }
01816
01817 return $sDelivCountry;
01818 }
01819
01825 public function deleteBasket()
01826 {
01827 $this->_aBasketContents = array();
01828 $this->getSession()->delBasket();
01829
01830 if ($this->getConfig()->getConfigParam( 'blPsBasketReservationEnabled' )) {
01831 $this->getSession()->getBasketReservations()->discardReservations();
01832 }
01833
01834
01835 $this->_deleteSavedBasket();
01836 }
01837
01845 public function setPayment( $sPaymentId = null )
01846 {
01847 $this->_sPaymentId = $sPaymentId;
01848 }
01849
01855 public function getPaymentId()
01856 {
01857 if ( !$this->_sPaymentId ) {
01858 $this->_sPaymentId = oxSession::getVar( 'paymentid' );
01859 }
01860 return $this->_sPaymentId;
01861 }
01862
01870 public function setShipping( $sShippingSetId = null )
01871 {
01872 $this->_sShippingSetId = $sShippingSetId;
01873 oxSession::setVar( 'sShipSet', $sShippingSetId );
01874 }
01875
01883 public function setDeliveryPrice( $oShippingPrice = null )
01884 {
01885 $this->_oDeliveryPrice = $oShippingPrice;
01886 }
01887
01893 public function getShippingId()
01894 {
01895 if ( !$this->_sShippingSetId ) {
01896 $this->_sShippingSetId = oxSession::getVar( 'sShipSet' );
01897 }
01898
01899 $sActPaymentId = $this->getPaymentId();
01900
01901 if ( !$this->_sShippingSetId && $sActPaymentId != 'oxempty' ) {
01902 $oUser = $this->getUser();
01903
01904
01905 list( , $sActShipSet ) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData( null, $oUser, $this );
01906
01907 $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ( $oUser ? null : 'oxidstandard' );
01908 } elseif ( !$this->isAdmin() && $sActPaymentId == 'oxempty' ) {
01909
01910 $this->_sShippingSetId = null;
01911 }
01912
01913 return $this->_sShippingSetId;
01914 }
01915
01921 public function getBasketArticles()
01922 {
01923 $aBasketArticles = array();
01924
01925 foreach ( $this->_aBasketContents as $sItemKey => $oBasketItem ) {
01926 try {
01927 $oProduct = $oBasketItem->getArticle( true );
01928
01929 if ( $this->getConfig()->getConfigParam( 'bl_perfLoadSelectLists' ) ) {
01930
01931 $aSelList = $oBasketItem->getSelList();
01932 if ( is_array( $aSelList ) && ( $aSelectlist = $oProduct->getSelectLists( $sItemKey ) ) ) {
01933 reset( $aSelList );
01934 while ( list( $conkey, $iSel ) = each( $aSelList ) ) {
01935 $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01936 $aSelectlist[$conkey][$iSel]->selected = 1;
01937 }
01938 $oProduct->setSelectlist( $aSelectlist );
01939 }
01940 }
01941 } catch ( oxNoArticleException $oEx ) {
01942 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01943 $this->removeItem( $sItemKey );
01944 $this->calculateBasket( true );
01945 continue;
01946 } catch ( oxArticleInputException $oEx ) {
01947 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
01948 $this->removeItem( $sItemKey );
01949 $this->calculateBasket( true );
01950 continue;
01951 }
01952
01953 $aBasketArticles[$sItemKey] = $oProduct;
01954 }
01955 return $aBasketArticles;
01956 }
01957
01963 public function getDiscountProductsPrice()
01964 {
01965 return $this->_oDiscountProductsPriceList;
01966 }
01967
01973 public function getProductsPrice()
01974 {
01975 if ( is_null($this->_oProductsPriceList) ) {
01976 $this->_oProductsPriceList = oxNew( 'oxPriceList' );
01977 }
01978
01979 return $this->_oProductsPriceList;
01980 }
01981
01987 public function getPrice()
01988 {
01989 if ( is_null($this->_oPrice) ) {
01990 $this->_oPrice = oxNew( 'oxprice' );
01991 }
01992
01993 return $this->_oPrice;
01994 }
01995
02002 public function getOrderId()
02003 {
02004 return $this->_sOrderId;
02005 }
02006
02014 public function setOrderId( $sId )
02015 {
02016 $this->_sOrderId = $sId;
02017 }
02018
02027 public function getCosts( $sId = null )
02028 {
02029
02030 if ( $sId ) {
02031 return isset( $this->_aCosts[$sId] )?$this->_aCosts[$sId]:null;
02032 }
02033 return $this->_aCosts;
02034 }
02035
02041 public function getVouchers()
02042 {
02043 return $this->_aVouchers;
02044 }
02045
02051 public function getProductsCount()
02052 {
02053 return $this->_iProductsCnt;
02054 }
02055
02061 public function getItemsCount()
02062 {
02063 return $this->_dItemsCnt;
02064 }
02065
02071 public function getWeight()
02072 {
02073 return $this->_dWeight;
02074 }
02075
02081 public function getContents()
02082 {
02083 return $this->_aBasketContents;
02084 }
02085
02093 public function getProductVats( $blFormatCurrency = true)
02094 {
02095 if ( !$this->_oNotDiscountedProductsPriceList ) {
02096 return array();
02097 }
02098
02099 $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo( $this->isCalculationModeNetto() );
02100
02101 $oUtils = oxRegistry::getUtils();
02102 foreach ( $this->_aDiscountedVats as $sKey => $dVat ) {
02103 if ( !isset( $aVats[$sKey] ) ) {
02104 $aVats[$sKey] = 0;
02105 }
02106
02107 $aVats[$sKey] += $oUtils->fRound( $dVat, $this->_oCurrency );
02108 }
02109
02110 if ( $blFormatCurrency ) {
02111 $oLang = oxRegistry::getLang();
02112 foreach ( $aVats as $sKey => $dVat ) {
02113 $aVats[$sKey] = $oLang->formatCurrency( $dVat, $this->getBasketCurrency() );
02114 }
02115 }
02116
02117 return $aVats;
02118 }
02119
02125 public function getDiscountedNettoPrice()
02126 {
02127 if ( $this->_oNotDiscountedProductsPriceList ) {
02128 return $this->_dDiscountedProductNettoPrice + $this->_oNotDiscountedProductsPriceList->getNettoSum();
02129 }
02130 return false;
02131 }
02132
02140 public function setCardMessage( $sMessage )
02141 {
02142 $this->_sCardMessage = $sMessage;
02143 }
02144
02150 public function getCardMessage()
02151 {
02152 return $this->_sCardMessage;
02153 }
02154
02162 public function setCardId( $sCardId )
02163 {
02164 $this->_sCardId = $sCardId;
02165 }
02166
02172 public function getCardId()
02173 {
02174 return $this->_sCardId;
02175 }
02176
02182 public function getCard()
02183 {
02184 $oCard = null;
02185 if ( $sCardId = $this->getCardId() ) {
02186 $oCard = oxNew( 'oxwrapping' );
02187 $oCard->load( $sCardId );
02188 $oCard->setWrappingVat( $this->getAdditionalServicesVatPercent() );
02189 }
02190 return $oCard;
02191 }
02192
02198 public function getTotalDiscount()
02199 {
02200 return $this->_oTotalDiscount;
02201 }
02202
02208 public function getDiscounts()
02209 {
02210 if ( $this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
02211 return null;
02212 }
02213
02214 return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
02215 }
02216
02222 public function getVoucherDiscount()
02223 {
02224 if ($this->getConfig()->getConfigParam( 'bl_showVouchers' )) {
02225 return $this->_oVoucherDiscount;
02226 }
02227 return null;
02228 }
02229
02237 public function setBasketCurrency( $oCurrency )
02238 {
02239 $this->_oCurrency = $oCurrency;
02240 }
02241
02247 public function getBasketCurrency()
02248 {
02249 if ( $this->_oCurrency === null ) {
02250 $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
02251 }
02252
02253 return $this->_oCurrency;
02254 }
02255
02263 public function setSkipVouchersChecking( $blSkipChecking = null )
02264 {
02265 $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
02266 }
02267
02273 public function hasSkipedDiscount()
02274 {
02275 return $this->_blSkipDiscounts;
02276 }
02277
02285 public function setSkipDiscounts( $blSkip )
02286 {
02287 $this->_blSkipDiscounts = $blSkip;
02288 }
02289
02295 public function getProductsNetPrice()
02296 {
02297 return oxRegistry::getLang()->formatCurrency( $this->getNettoSum(), $this->getBasketCurrency() );
02298 }
02299
02305 public function getFProductsPrice()
02306 {
02307 return oxRegistry::getLang()->formatCurrency( $this->getBruttoSum(), $this->getBasketCurrency() );
02308 }
02309
02315 public function getDelCostVatPercent()
02316 {
02317 return $this->getCosts( 'oxdelivery' )->getVat();
02318 }
02319
02325 public function getDelCostVat()
02326 {
02327 $dDelVAT = $this->getCosts( 'oxdelivery' )->getVatValue();
02328
02329
02330 if ( $dDelVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForDelivery' )) {
02331 return oxRegistry::getLang()->formatCurrency( $dDelVAT, $this->getBasketCurrency() );
02332 }
02333 return false;
02334 }
02335
02341 public function getDelCostNet()
02342 {
02343 $oConfig = $this->getConfig();
02344
02345
02346 if ( $oConfig->getConfigParam( 'blShowVATForDelivery' ) && ( $this->getBasketUser() || $oConfig->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02347 $dNetPrice = $this->getCosts( 'oxdelivery' )->getNettoPrice();
02348 if ( $dNetPrice > 0 ) {
02349 return oxRegistry::getLang()->formatCurrency( $dNetPrice, $this->getBasketCurrency() );
02350 }
02351 }
02352 return false;
02353 }
02354
02360 public function getPayCostVatPercent()
02361 {
02362 return $this->getCosts( 'oxpayment' )->getVat();
02363 }
02364
02370 public function getPayCostVat()
02371 {
02372 $dPayVAT = $this->getCosts( 'oxpayment' )->getVatValue();
02373
02374
02375 if ( $dPayVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02376 return oxRegistry::getLang()->formatCurrency( $dPayVAT, $this->getBasketCurrency() );
02377 }
02378 return false;
02379 }
02380
02386 public function getPayCostNet()
02387 {
02388
02389 if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02390 $oPaymentCost = $this->getCosts( 'oxpayment' );
02391 if ( $oPaymentCost && $oPaymentCost->getNettoPrice() ) {
02392 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxpayment' )->getNettoPrice(), $this->getBasketCurrency() );
02393 }
02394 }
02395 return false;
02396 }
02397
02403 public function getPaymentCosts()
02404 {
02405 $oPaymentCost = $this->getCosts( 'oxpayment' );
02406 if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02407 return $oPaymentCost->getBruttoPrice();
02408 }
02409 }
02410
02416 public function getFPaymentCosts()
02417 {
02418 $oPaymentCost = $this->getCosts( 'oxpayment' );
02419 if ( $oPaymentCost && $oPaymentCost->getBruttoPrice() ) {
02420 return oxRegistry::getLang()->formatCurrency( $oPaymentCost->getBruttoPrice(), $this->getBasketCurrency() );
02421 }
02422 return false;
02423 }
02424
02430 public function getVoucherDiscValue()
02431 {
02432 if ( $this->getVoucherDiscount() ) {
02433 return $this->getVoucherDiscount()->getBruttoPrice();
02434 }
02435 return false;
02436 }
02437
02443 public function getFVoucherDiscountValue()
02444 {
02445 if ( $oVoucherDiscount = $this->getVoucherDiscount() ) {
02446 if ( $oVoucherDiscount->getBruttoPrice() ) {
02447 return oxRegistry::getLang()->formatCurrency( $oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency() );
02448 }
02449 }
02450 return false;
02451 }
02452
02453
02459 public function getWrappCostVatPercent()
02460 {
02461 return $this->getCosts( 'oxwrapping' )->getVat();
02462 }
02463
02464
02470 public function getGiftCardCostVatPercent()
02471 {
02472 return $this->getCosts( 'oxgiftcard' )->getVat();
02473 }
02474
02480 public function getWrappCostVat()
02481 {
02482
02483 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02484 $oPrice = $this->getCosts( 'oxwrapping' );
02485
02486 if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02487 return oxRegistry::getLang()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02488 }
02489 }
02490
02491 return false;
02492 }
02493
02499 public function getWrappCostNet()
02500 {
02501
02502 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02503 $oPrice = $this->getCosts( 'oxwrapping' );
02504
02505 if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02506 return oxRegistry::getLang()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02507 }
02508 }
02509
02510 return false;
02511 }
02512
02518 public function getFWrappingCosts()
02519 {
02520 $oPrice = $this->getCosts( 'oxwrapping' );
02521
02522 if ( $oPrice && $oPrice->getBruttoPrice() ) {
02523 return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02524 }
02525
02526 return false;
02527 }
02528
02529
02535 public function getGiftCardCostVat()
02536 {
02537
02538 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02539 $oPrice = $this->getCosts( 'oxgiftcard' );
02540
02541 if ( $oPrice && $oPrice->getVatValue() > 0 ) {
02542 return oxLang::getInstance()->formatCurrency( $oPrice->getVatValue(), $this->getBasketCurrency() );
02543 }
02544 }
02545
02546 return false;
02547
02548 }
02549
02555 public function getGiftCardCostNet()
02556 {
02557
02558 if ( $this->getConfig()->getConfigParam( 'blShowVATForWrapping' ) ) {
02559 $oPrice = $this->getCosts( 'oxgiftcard' );
02560
02561 if ( $oPrice && $oPrice->getNettoPrice() > 0 ) {
02562 return oxLang::getInstance()->formatCurrency( $oPrice->getNettoPrice(), $this->getBasketCurrency() );
02563 }
02564 }
02565
02566 return false;
02567 }
02568
02574 public function getFGiftCardCosts()
02575 {
02576 $oPrice = $this->getCosts( 'oxgiftcard' );
02577
02578 if ( $oPrice && $oPrice->getBruttoPrice() ) {
02579 return oxLang::getInstance()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02580 }
02581 return false;
02582 }
02583
02589 public function getFPrice()
02590 {
02591 return oxRegistry::getLang()->formatCurrency( $this->getPrice()->getBruttoPrice(), $this->getBasketCurrency() );
02592 }
02593
02599 public function getFDeliveryCosts()
02600 {
02601 $oPrice = $this->getCosts( 'oxdelivery' );
02602
02603 if ( $oPrice && ( $this->getBasketUser() || $this->getConfig()->getConfigParam( 'blCalculateDelCostIfNotLoggedIn' ) ) ) {
02604 return oxRegistry::getLang()->formatCurrency( $oPrice->getBruttoPrice(), $this->getBasketCurrency() );
02605 }
02606 return false;
02607 }
02608
02614 public function getDeliveryCosts()
02615 {
02616 if ( $oDeliveryCost = $this->getCosts( 'oxdelivery' ) ) {
02617 return $oDeliveryCost->getBruttoPrice();
02618 }
02619 return false;
02620 }
02621
02629 public function setTotalDiscount( $dDiscount )
02630 {
02631 $this->_oTotalDiscount = oxNew( 'oxPrice' );
02632 $this->_oTotalDiscount->setBruttoPriceMode();
02633 $this->_oTotalDiscount->add( $dDiscount );
02634 }
02635
02642 public function getPriceForPayment()
02643 {
02644 $dPrice = $this->getDiscountedProductsBruttoPrice();
02645
02646 if ( $oPriceList = $this->getNotDiscountProductsPrice() ) {
02647 $dPrice += $oPriceList->getBruttoSum();
02648 }
02649
02650
02651 if ( $oDeliveryPrice = $this->_aCosts['oxdelivery'] ) {
02652 $dPrice += $oDeliveryPrice->getBruttoPrice();
02653 }
02654
02655 return $dPrice;
02656 }
02657
02658
02664 public function _getDiscountedProductsSum()
02665 {
02666 if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02667 $dPrice = $oProductsPrice->getSum( $this->isCalculationModeNetto() );
02668 }
02669
02670
02671 if ( $oPrice = $this->getTotalDiscount() ) {
02672 $dPrice -= $oPrice->getPrice();
02673 }
02674
02675 if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02676 $dPrice -= $oVoucherPrice->getPrice();
02677 }
02678
02679 return $dPrice;
02680 }
02681
02687 public function getDiscountedProductsBruttoPrice()
02688 {
02689 if ( $oProductsPrice = $this->getDiscountProductsPrice() ) {
02690 $dPrice = $oProductsPrice->getBruttoSum();
02691 }
02692
02693
02694 if ( $oPrice = $this->getTotalDiscount() ) {
02695 $dPrice -= $oPrice->getBruttoPrice();
02696 }
02697
02698 if ( $oVoucherPrice = $this->getVoucherDiscount() ) {
02699 $dPrice -= $oVoucherPrice->getBruttoPrice();
02700 }
02701
02702 return $dPrice;
02703 }
02704
02710 public function isBelowMinOrderPrice()
02711 {
02712 $blIsBelowMinOrderPrice = false;
02713 $sConfValue = $this->getConfig()->getConfigParam( 'iMinOrderPrice' );
02714 if ( is_numeric($sConfValue) && $this->getProductsCount() ) {
02715 $dMinOrderPrice = oxPrice::getPriceInActCurrency( ( int ) $sConfValue );
02716 $dNotDiscountedProductPrice = 0;
02717 if ( $oPrice = $this->getNotDiscountProductsPrice() ) {
02718 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02719 }
02720 $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02721 }
02722
02723 return $blIsBelowMinOrderPrice;
02724
02725 }
02726
02735 public function getArtStockInBasket( $sArtId, $sExpiredArtId = null )
02736 {
02737 $dArtStock = 0;
02738 foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
02739 if ( $oOrderArticle && ( $sExpiredArtId == null || $sExpiredArtId != $sItemKey ) ) {
02740 if ( $oOrderArticle->getArticle( true )->getId() == $sArtId ) {
02741 $dArtStock += $oOrderArticle->getAmount();
02742 }
02743 }
02744 }
02745
02746 return $dArtStock;
02747 }
02748
02756 public function canAddProductToBasket( $sProductId )
02757 {
02758 $blCanAdd = null;
02759
02760
02761 if ( $this->_sBasketCategoryId === null ) {
02762 $oCat = null;
02763
02764
02765 if ( $oView = $this->getConfig()->getActiveView() ) {
02766 if ( $oCat = $oView->getActCategory() ) {
02767 if ( !$this->_isProductInRootCategory( $sProductId, $oCat->oxcategories__oxrootid->value ) ) {
02768 $oCat = null;
02769 } else {
02770 $blCanAdd = true;
02771 }
02772 }
02773 }
02774
02775
02776 if ( !$oCat ) {
02777 $oProduct = oxNew( "oxarticle" );
02778 if ( $oProduct->load( $sProductId ) ) {
02779 $oCat = $oProduct->getCategory();
02780 }
02781 }
02782
02783
02784 if ( $oCat ) {
02785 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02786 }
02787 }
02788
02789
02790 if ( $blCanAdd === null ) {
02791 $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory( $sProductId, $this->getBasketRootCatId() ) : true;
02792 }
02793
02794 return $blCanAdd;
02795 }
02796
02805 protected function _isProductInRootCategory( $sProductId, $sRootCatId )
02806 {
02807 $sO2CTable = getViewName( 'oxobject2category' );
02808 $sCatTable = getViewName( 'oxcategories' );
02809
02810 $oDb = oxDb::getDb();
02811 $sParentId = $oDb->getOne( "select oxparentid from oxarticles where oxid = ".$oDb->quote( $sProductId ) );
02812 $sProductId = $sParentId ? $sParentId : $sProductId;
02813
02814 $sQ = "select 1 from {$sO2CTable}
02815 left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02816 where {$sO2CTable}.oxobjectid = ".$oDb->quote( $sProductId )." and
02817 {$sCatTable}.oxrootid = ".$oDb->quote( $sRootCatId );
02818
02819 return (bool) $oDb->getOne( $sQ );
02820 }
02821
02829 public function setBasketRootCatId($sRoot)
02830 {
02831 $this->_sBasketCategoryId = $sRoot;
02832 }
02833
02839 public function getBasketRootCatId()
02840 {
02841 return $this->_sBasketCategoryId;
02842 }
02843
02851 public function setCatChangeWarningState( $blShow )
02852 {
02853 $this->_blShowCatChangeWarning = $blShow;
02854 }
02855
02861 public function showCatChangeWarning()
02862 {
02863 return $this->_blShowCatChangeWarning;
02864 }
02865
02873 public function setTsProductId( $sProductId )
02874 {
02875 $this->_sTsProductId = $sProductId;
02876 }
02877
02883 public function getTsProductId()
02884 {
02885 return $this->_sTsProductId;
02886 }
02887
02893 public function getFTsProtectionCosts()
02894 {
02895 $oProtectionCost = $this->getCosts( 'oxtsprotection' );
02896 if ( $oProtectionCost && $oProtectionCost->getBruttoPrice() ) {
02897 return oxRegistry::getLang()->formatCurrency( $oProtectionCost->getBruttoPrice(), $this->getBasketCurrency() );
02898 }
02899 return false;
02900 }
02901
02907 public function getTsProtectionVatPercent()
02908 {
02909 return $this->getCosts( 'oxtsprotection' )->getVat();
02910 }
02911
02917 public function getTsProtectionVat()
02918 {
02919 $dProtectionVAT = $this->getCosts( 'oxtsprotection' )->getVatValue();
02920
02921 if ( $dProtectionVAT > 0 && $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02922 return oxRegistry::getLang()->formatCurrency( $dProtectionVAT, $this->getBasketCurrency() );
02923 }
02924 return false;
02925 }
02926
02932 public function getTsProtectionNet()
02933 {
02934
02935 if ( $this->getConfig()->getConfigParam( 'blShowVATForPayCharge' ) ) {
02936 return oxRegistry::getLang()->formatCurrency( $this->getCosts( 'oxtsprotection' )->getNettoPrice(), $this->getBasketCurrency() );
02937 }
02938 return false;
02939 }
02940
02946 public function getTsProtectionCosts()
02947 {
02948 $oProtection = $this->getCosts( 'oxtsprotection' );
02949 if ( $oProtection ) {
02950 return $oProtection->getBruttoPrice();
02951 }
02952 return false;
02953 }
02954
02960 public function getNotDiscountProductsPrice()
02961 {
02962 return $this->_oNotDiscountedProductsPriceList;
02963 }
02964
02978 protected function _addedNewItem( $sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId )
02979 {
02980 if ( !$blOverride ) {
02981 $this->_blNewITemAdded = null;
02982 oxSession::setVar( "blAddedNewItem", true );
02983 }
02984 }
02985
02991 public function __wakeUp()
02992 {
02993 $this->_blNewITemAdded = null;
02994 $this->_isCalculationModeNetto = null;
02995 }
02996
03002 public function isNewItemAdded()
03003 {
03004 if ( $this->_blNewITemAdded == null ) {
03005 $this->_blNewITemAdded = (bool) oxSession::getVar( "blAddedNewItem" );
03006 oxSession::deleteVar( "blAddedNewItem" );
03007 }
03008 return $this->_blNewITemAdded;
03009 }
03010
03016 public function hasDownloadableProducts()
03017 {
03018 $this->_blDownloadableProducts = false;
03019 foreach ( $this->_aBasketContents as $sItemKey => $oOrderArticle ) {
03020 if ( $oOrderArticle->getArticle( false ) && $oOrderArticle->getArticle( false )->isDownloadable() ) {
03021 $this->_blDownloadableProducts = true;
03022 break;
03023 }
03024 }
03025
03026 return $this->_blDownloadableProducts;
03027 }
03028
03029 }