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