00001 <?php
00002
00007 class oxBasket extends oxSuperCfg
00008 {
00009
00015 protected $_aBasketContents = array();
00016
00022 protected $_iProductsCnt = 0;
00023
00029 protected $_dItemsCnt = 0.0;
00030
00036 protected $_dWeight = 0.0;
00037
00043 protected $_oPrice = null;
00044
00050 protected $_isCalculationModeNetto = null;
00051
00057 protected $_dNettoSum = null;
00058
00064 protected $_dBruttoSum = null;
00065
00071 protected $_oProductsPriceList = null;
00072
00078 protected $_aDiscounts = array();
00079
00085 protected $_aItemDiscounts = array();
00086
00092 protected $_sOrderId = null;
00093
00099 protected $_aVouchers = array();
00100
00106 protected $_aCosts = array();
00107
00113 protected $_oDiscountProductsPriceList = null;
00114
00120 protected $_oNotDiscountedProductsPriceList = null;
00121
00127 protected $_blUpdateNeeded = true;
00128
00134 protected $_aBasketSummary = null;
00135
00141 protected $_sPaymentId = null;
00142
00148 protected $_sShippingSetId = null;
00149
00155 protected $_oUser = null;
00156
00162 protected $_oTotalDiscount = null;
00163
00169 protected $_oVoucherDiscount = null;
00170
00176 protected $_oCurrency = null;
00177
00183 protected $_blSkipVouchersAvailabilityChecking = null;
00184
00190 protected $_dDiscountedProductNettoPrice = null;
00191
00197 protected $_aDiscountedVats = null;
00198
00204 protected $_blSkipDiscounts = false;
00205
00211 protected $_oDeliveryPrice = null;
00212
00218 protected $_blCheckStock = true;
00219
00225 protected $_blCalcDiscounts = true;
00226
00232 protected $_sBasketCategoryId = null;
00233
00239 protected $_blShowCatChangeWarning = false;
00240
00246 protected $_sTsProductId = null;
00247
00253 protected $_blNewITemAdded = null;
00254
00260 protected $_blDownloadableProducts = null;
00261
00262
00268 protected $_blSaveToDataBase = null;
00269
00275 public function enableSaveToDataBase($blSave = true)
00276 {
00277 $this->_blSaveToDataBase = $blSave;
00278 }
00279
00285 public function isSaveToDataBaseEnabled()
00286 {
00287 if (is_null($this->_blSaveToDataBase)) {
00288 $this->_blSaveToDataBase = (bool) !$this->getConfig()->getConfigParam('blPerfNoBasketSaving');
00289 }
00290
00291 return $this->_blSaveToDataBase;
00292 }
00293
00294
00300 public function isCalculationModeNetto()
00301 {
00302 if ($this->_isCalculationModeNetto === null) {
00303 $this->setCalculationModeNetto($this->isPriceViewModeNetto());
00304 }
00305
00306 return $this->_isCalculationModeNetto;
00307 }
00308
00314 public function setCalculationModeNetto($blNettoMode = true)
00315 {
00316 $this->_isCalculationModeNetto = (bool) $blNettoMode;
00317 }
00318
00324 public function getNettoSum()
00325 {
00326 return $this->_dNettoSum;
00327 }
00328
00334 public function getBruttoSum()
00335 {
00336 return $this->_dBruttoSum;
00337 }
00338
00344 public function setNettoSum($dNettoSum)
00345 {
00346 $this->_dNettoSum = $dNettoSum;
00347 }
00348
00354 public function setBruttoSum($dBruttoSum)
00355 {
00356 $this->_dBruttoSum = $dBruttoSum;
00357 }
00358
00364 public function isEnabled()
00365 {
00366 return !oxRegistry::getUtils()->isSearchEngine();
00367 }
00368
00376 protected function _changeBasketItemKey($sOldKey, $sNewKey, $value = null)
00377 {
00378 reset($this->_aBasketContents);
00379 $iOldKeyPlace = 0;
00380 while (key($this->_aBasketContents) != $sOldKey && next($this->_aBasketContents)) {
00381 ++$iOldKeyPlace;
00382 }
00383 $aNewCopy = array_merge(
00384 array_slice($this->_aBasketContents, 0, $iOldKeyPlace, true),
00385 array($sNewKey => $value),
00386 array_slice($this->_aBasketContents, $iOldKeyPlace + 1, count($this->_aBasketContents) - $iOldKeyPlace, true)
00387 );
00388 $this->_aBasketContents = $aNewCopy;
00389 }
00390
00406 public function addToBasket($sProductID, $dAmount, $aSel = null, $aPersParam = null, $blOverride = false, $blBundle = false, $sOldBasketItemId = null)
00407 {
00408
00409 if (!$this->isEnabled()) {
00410 return null;
00411 }
00412
00413
00414 if ($this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
00415 if (!$this->canAddProductToBasket($sProductID)) {
00416 $this->setCatChangeWarningState(true);
00417
00418 return null;
00419 } else {
00420 $this->setCatChangeWarningState(false);
00421 }
00422 }
00423
00424 $sItemId = $this->getItemKey($sProductID, $aSel, $aPersParam, $blBundle);
00425 if ($sOldBasketItemId && (strcmp($sOldBasketItemId, $sItemId) != 0)) {
00426 if (isset($this->_aBasketContents[$sItemId])) {
00427
00428 unset($this->_aBasketContents[$sOldBasketItemId]);
00429
00430 $blOverride = false;
00431 } else {
00432
00433 $this->_changeBasketItemKey($sOldBasketItemId, $sItemId);
00434 }
00435 }
00436
00437
00438 $blRemoveItem = false;
00439
00440
00441 $oEx = null;
00442
00443 if (isset($this->_aBasketContents[$sItemId])) {
00444
00445
00446 try {
00447
00448 $this->_aBasketContents[$sItemId]->setStockCheckStatus($this->getStockCheckMode());
00449
00450
00451 $this->_aBasketContents[$sItemId]->setAmount($dAmount, $blOverride, $sItemId);
00452 } catch (oxOutOfStockException $oEx) {
00453
00454 }
00455
00456 } else {
00457
00458 $oBasketItem = oxNew('oxbasketitem');
00459 try {
00460 $oBasketItem->setStockCheckStatus($this->getStockCheckMode());
00461 $oBasketItem->init($sProductID, $dAmount, $aSel, $aPersParam, $blBundle);
00462 } catch (oxNoArticleException $oEx) {
00463
00464
00465 $blRemoveItem = true;
00466
00467 } catch (oxOutOfStockException $oEx) {
00468
00469 } catch (oxArticleInputException $oEx) {
00470
00471 $blRemoveItem = true;
00472 }
00473
00474 $this->_aBasketContents[$sItemId] = $oBasketItem;
00475 }
00476
00477
00478 if ($this->_aBasketContents[$sItemId]->getAmount() == 0 || $blRemoveItem) {
00479 $this->removeItem($sItemId);
00480 } elseif ($blBundle) {
00481
00482 $this->_aBasketContents[$sItemId]->setBundle(true);
00483 }
00484
00485
00486 $this->onUpdate();
00487
00488 if ($oEx) {
00489 throw $oEx;
00490 }
00491
00492
00493 if (!$blBundle) {
00494 $this->_addedNewItem($sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId);
00495 }
00496
00497
00498 return $this->_aBasketContents[$sItemId];
00499 }
00500
00508 public function addOrderArticleToBasket($oOrderArticle)
00509 {
00510
00511 if ($oOrderArticle->oxorderarticles__oxamount->value > 0 && !$oOrderArticle->isBundle()) {
00512
00513 $this->_isForOrderRecalculation = true;
00514 $sItemId = $oOrderArticle->getId();
00515
00516
00517 $this->_aBasketContents[$sItemId] = oxNew('oxbasketitem');
00518 $this->_aBasketContents[$sItemId]->initFromOrderArticle($oOrderArticle);
00519 $this->_aBasketContents[$sItemId]->setWrapping($oOrderArticle->oxorderarticles__oxwrapid->value);
00520 $this->_aBasketContents[$sItemId]->setBundle($oOrderArticle->isBundle());
00521
00522
00523 $this->onUpdate();
00524
00525 return $this->_aBasketContents[$sItemId];
00526 } elseif ($oOrderArticle->isBundle()) {
00527
00528 $oOrderArticle->delete();
00529 }
00530 }
00531
00537 public function setStockCheckMode($blCheck)
00538 {
00539 $this->_blCheckStock = $blCheck;
00540 }
00541
00547 public function getStockCheckMode()
00548 {
00549 return $this->_blCheckStock;
00550 }
00551
00564 public function getItemKey($sProductId, $aSel = null, $aPersParam = null, $blBundle = false, $sAdditionalParam = '')
00565 {
00566 $aSel = ($aSel != null) ? $aSel : array(0 => '0');
00567
00568 $sItemKey = md5($sProductId . '|' . serialize($aSel) . '|' . serialize($aPersParam) . '|' . ( int ) $blBundle . '|' . serialize($sAdditionalParam));
00569
00570 return $sItemKey;
00571 }
00572
00573
00579 public function removeItem($sItemKey)
00580 {
00581 if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
00582 if (isset($this->_aBasketContents[$sItemKey])) {
00583 $sArticleId = $this->_aBasketContents[$sItemKey]->getProductId();
00584 if ($sArticleId) {
00585 $this->getSession()
00586 ->getBasketReservations()
00587 ->discardArticleReservation($sArticleId);
00588 }
00589 }
00590 }
00591 unset($this->_aBasketContents[$sItemKey]);
00592
00593
00594 if (!count($this->_aBasketContents) && $this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
00595 $this->setBasketRootCatId(null);
00596 }
00597 }
00598
00602 protected function _clearBundles()
00603 {
00604 reset($this->_aBasketContents);
00605 while (list($sItemKey, $oBasketItem) = each($this->_aBasketContents)) {
00606 if ($oBasketItem->isBundle()) {
00607 $this->removeItem($sItemKey);
00608 }
00609 }
00610 }
00611
00619 protected function _getArticleBundles($oBasketItem)
00620 {
00621 $aBundles = array();
00622
00623 if ($oBasketItem->isBundle()) {
00624 return $aBundles;
00625 }
00626
00627 $oArticle = $oBasketItem->getArticle(true);
00628 if ($oArticle && $oArticle->oxarticles__oxbundleid->value) {
00629 $aBundles[$oArticle->oxarticles__oxbundleid->value] = 1;
00630 }
00631
00632 return $aBundles;
00633 }
00634
00635
00644 protected function _getItemBundles($oBasketItem, $aBundles = array())
00645 {
00646 if ($oBasketItem->isBundle()) {
00647 return array();
00648 }
00649
00650
00651 if ($oArticle = $oBasketItem->getArticle()) {
00652 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketItemBundleDiscounts($oArticle, $this, $this->getBasketUser());
00653
00654 foreach ($aDiscounts as $oDiscount) {
00655
00656 $iAmnt = $oDiscount->getBundleAmount($oBasketItem->getAmount());
00657 if ($iAmnt) {
00658
00659 if (!isset($aBundles[$oDiscount->oxdiscount__oxitmartid->value])) {
00660 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00661 }
00662
00663 if ($oDiscount->oxdiscount__oxitmmultiple->value) {
00664 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $iAmnt;
00665 } else {
00666 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = $iAmnt;
00667 }
00668 }
00669 }
00670 }
00671
00672 return $aBundles;
00673 }
00674
00682 protected function _getBasketBundles($aBundles = array())
00683 {
00684 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketBundleDiscounts($this, $this->getBasketUser());
00685
00686
00687 $dAmount = 0;
00688 foreach ($this->_aBasketContents as $oBasketItem) {
00689 if (!($oBasketItem->isBundle() || $oBasketItem->isDiscountArticle())) {
00690 $dAmount += $oBasketItem->getAmount();
00691 }
00692 }
00693
00694 foreach ($aDiscounts as $oDiscount) {
00695 if ($oDiscount->oxdiscount__oxitmartid->value) {
00696 if (!isset($aBundles[$oDiscount->oxdiscount__oxitmartid->value])) {
00697 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
00698 }
00699
00700 $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $oDiscount->getBundleAmount($dAmount);
00701 }
00702 }
00703
00704 return $aBundles;
00705 }
00706
00711 protected function _addBundles()
00712 {
00713 $aBundles = array();
00714
00715 foreach ($this->_aBasketContents as $key => $oBasketItem) {
00716 try {
00717
00718 if (!$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle()) {
00719 $aBundles = $this->_getItemBundles($oBasketItem, $aBundles);
00720 } else {
00721 continue;
00722 }
00723
00724
00725 $aArtBundles = $this->_getArticleBundles($oBasketItem);
00726
00727
00728 $this->_addBundlesToBasket($aArtBundles);
00729 } catch (oxNoArticleException $oEx) {
00730 $this->removeItem($key);
00731 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
00732 } catch (oxArticleInputException $oEx) {
00733 $this->removeItem($key);
00734 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
00735 }
00736 }
00737
00738
00739 $aBundles = $this->_getBasketBundles($aBundles);
00740
00741
00742 if ($aBundles) {
00743 $this->_addBundlesToBasket($aBundles);
00744 }
00745 }
00746
00752 protected function _addBundlesToBasket($aBundles)
00753 {
00754 foreach ($aBundles as $sBundleId => $dAmount) {
00755 if ($dAmount) {
00756 try {
00757 if ($oBundleItem = $this->addToBasket($sBundleId, $dAmount, null, null, false, true)) {
00758 $oBundleItem->setAsDiscountArticle(true);
00759 }
00760 } catch (oxArticleException $oEx) {
00761
00762 if ($oEx instanceof oxOutOfStockException && $oEx->getRemainingAmount() > 0) {
00763 $sItemId = $this->getItemKey($sBundleId, null, null, true);
00764 $this->_aBasketContents[$sItemId]->setAsDiscountArticle( true );
00765 }
00766 }
00767 }
00768 }
00769
00770 }
00771
00775 protected function _calcItemsPrice()
00776 {
00777
00778 $this->setSkipDiscounts(false);
00779 $this->_iProductsCnt = 0;
00780 $this->_dItemsCnt = 0;
00781 $this->_dWeight = 0;
00782
00783 $this->_oProductsPriceList = oxNew('oxpricelist');
00784 $this->_oDiscountProductsPriceList = oxNew('oxpricelist');
00785 $this->_oNotDiscountedProductsPriceList = oxNew('oxpricelist');
00786
00787 $oDiscountList = oxRegistry::get("oxDiscountList");
00788
00789 foreach ($this->_aBasketContents as $oBasketItem) {
00790 $this->_iProductsCnt++;
00791 $this->_dItemsCnt += $oBasketItem->getAmount();
00792 $this->_dWeight += $oBasketItem->getWeight();
00793
00794 if (!$oBasketItem->isDiscountArticle() && ($oArticle = $oBasketItem->getArticle(true))) {
00795
00796 $oBasketPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this);
00797 $oBasketItem->setRegularUnitPrice(clone $oBasketPrice);
00798
00799 if (!$oArticle->skipDiscounts() && $this->canCalcDiscounts()) {
00800
00801 $aDiscounts = $oDiscountList->getBasketItemDiscounts($oArticle, $this, $this->getBasketUser());
00802 reset($aDiscounts);
00803 foreach ($aDiscounts as $oDiscount) {
00804 $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
00805 }
00806 $oBasketPrice->calculateDiscount();
00807 } else {
00808 $oBasketItem->setSkipDiscounts(true);
00809 $this->setSkipDiscounts(true);
00810 }
00811
00812 $oBasketItem->setPrice($oBasketPrice);
00813 $this->_oProductsPriceList->addToPriceList($oBasketItem->getPrice());
00814
00815
00816 if (!$oArticle->skipDiscounts()) {
00817
00818 $this->_oDiscountProductsPriceList->addToPriceList($oBasketItem->getPrice());
00819 } else {
00820 $this->_oNotDiscountedProductsPriceList->addToPriceList($oBasketItem->getPrice());
00821 $oBasketItem->setSkipDiscounts(true);
00822 $this->setSkipDiscounts(true);
00823 }
00824 } elseif ($oBasketItem->isBundle()) {
00825
00826 $oPrice = oxNew("oxprice");
00827 $oBasketItem->setPrice($oPrice);
00828 }
00829 }
00830 }
00831
00837 public function setDiscountCalcMode($blCalcDiscounts)
00838 {
00839 $this->_blCalcDiscounts = $blCalcDiscounts;
00840 }
00841
00847 public function canCalcDiscounts()
00848 {
00849 return $this->_blCalcDiscounts;
00850 }
00851
00861 protected function _mergeDiscounts($aDiscounts, $aItemDiscounts)
00862 {
00863 foreach ($aItemDiscounts as $sKey => $oDiscount) {
00864
00865 if (array_key_exists($sKey, $aDiscounts)) {
00866 $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
00867 } else {
00868 $aDiscounts[$sKey] = $oDiscount;
00869 }
00870 }
00871
00872 return $aDiscounts;
00873 }
00874
00880 protected function _calcDeliveryCost()
00881 {
00882 if ($this->_oDeliveryPrice !== null) {
00883 return $this->_oDeliveryPrice;
00884 }
00885 $myConfig = $this->getConfig();
00886 $oDeliveryPrice = oxNew('oxprice');
00887
00888 if ($this->getConfig()->getConfigParam('blDeliveryVatOnTop')) {
00889 $oDeliveryPrice->setNettoPriceMode();
00890 } else {
00891 $oDeliveryPrice->setBruttoPriceMode();
00892 }
00893
00894
00895 $oUser = $this->getBasketUser();
00896
00897 if (!$oUser && !$myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn')) {
00898 return $oDeliveryPrice;
00899 }
00900
00901 $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00902 $oDeliveryPrice->setVat($fDelVATPercent);
00903
00904
00905 if ($myConfig->getConfigParam('bl_perfLoadDelivery')) {
00906 $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList(
00907 $this,
00908 $oUser,
00909 $this->_findDelivCountry(),
00910 $this->getShippingId()
00911 );
00912
00913 if (count($aDeliveryList) > 0) {
00914 foreach ($aDeliveryList as $oDelivery) {
00915
00916 if ($myConfig->getConfigParam('iDebug') == 5) {
00917 echo("DelCost : " . $oDelivery->oxdelivery__oxtitle->value . "<br>");
00918 }
00919 $oDeliveryPrice->addPrice($oDelivery->getDeliveryPrice($fDelVATPercent));
00920 }
00921 }
00922 }
00923
00924 return $oDeliveryPrice;
00925 }
00926
00932 public function getBasketUser()
00933 {
00934 if ($this->_oUser == null) {
00935 return $this->getUser();
00936 }
00937
00938 return $this->_oUser;
00939 }
00940
00946 public function setBasketUser($oUser)
00947 {
00948 $this->_oUser = $oUser;
00949 }
00950
00951
00957 public function getMostUsedVatPercent()
00958 {
00959 if ($this->_oProductsPriceList) {
00960 return $this->_oProductsPriceList->getMostUsedVatPercent();
00961 }
00962 }
00963
00969 public function getAdditionalServicesVatPercent()
00970 {
00971 if ($this->_oProductsPriceList) {
00972 if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
00973 return $this->_oProductsPriceList->getProportionalVatPercent();
00974 } else {
00975 return $this->_oProductsPriceList->getMostUsedVatPercent();
00976 }
00977 }
00978 }
00979
00985 public function isProportionalCalculationOn()
00986 {
00987 if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
00988 return true;
00989 }
00990
00991 return false;
00992 }
00993
00994
00995
00999 protected function _calcTotalPrice()
01000 {
01001
01002 $dPrice = $this->_dBruttoSum;
01003
01004 $oTotalPrice = oxNew('oxPrice');
01005 $oTotalPrice->setBruttoPriceMode();
01006 $oTotalPrice->setPrice($dPrice);
01007
01008
01009 if ($dPrice && !$this->isCalculationModeNetto()) {
01010
01011
01012 $oTotalPrice->subtract($this->_oTotalDiscount->getBruttoPrice());
01013
01014
01015 if ($oVoucherDisc = $this->getVoucherDiscount()) {
01016 $oTotalPrice->subtract($oVoucherDisc->getBruttoPrice());
01017 }
01018 }
01019
01020
01021 if (isset($this->_aCosts['oxdelivery'])) {
01022 $oTotalPrice->add($this->_aCosts['oxdelivery']->getBruttoPrice());
01023 }
01024
01025
01026 if (isset($this->_aCosts['oxwrapping'])) {
01027 $oTotalPrice->add($this->_aCosts['oxwrapping']->getBruttoPrice());
01028 }
01029 if (isset($this->_aCosts['oxgiftcard'])) {
01030 $oTotalPrice->add($this->_aCosts['oxgiftcard']->getBruttoPrice());
01031 }
01032
01033
01034 if (isset($this->_aCosts['oxpayment'])) {
01035 $oTotalPrice->add($this->_aCosts['oxpayment']->getBruttoPrice());
01036 }
01037
01038
01039 if (isset($this->_aCosts['oxtsprotection'])) {
01040 $oTotalPrice->add($this->_aCosts['oxtsprotection']->getBruttoPrice());
01041 }
01042
01043 $this->setPrice($oTotalPrice);
01044 }
01045
01051 public function setVoucherDiscount($dDiscount)
01052 {
01053 $this->_oVoucherDiscount = oxNew('oxPrice');
01054 $this->_oVoucherDiscount->setBruttoPriceMode();
01055 $this->_oVoucherDiscount->add($dDiscount);
01056 }
01057
01061 protected function _calcVoucherDiscount()
01062 {
01063 if ($this->getConfig()->getConfigParam('bl_showVouchers') && ($this->_oVoucherDiscount === null || ($this->_blUpdateNeeded && !$this->isAdmin()))) {
01064
01065 $this->_oVoucherDiscount = $this->_getPriceObject();
01066
01067
01068 $dPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto()) - $this->_oTotalDiscount->getPrice();
01069
01070
01071 if (count($this->_aVouchers)) {
01072 $oLang = oxRegistry::getLang();
01073 foreach ($this->_aVouchers as $sVoucherId => $oStdVoucher) {
01074 $oVoucher = oxNew('oxvoucher');
01075 try {
01076 $oVoucher->load($oStdVoucher->sVoucherId);
01077
01078 if (!$this->_blSkipVouchersAvailabilityChecking) {
01079 $oVoucher->checkBasketVoucherAvailability($this->_aVouchers, $dPrice);
01080 $oVoucher->checkUserAvailability($this->getBasketUser());
01081 }
01082
01083
01084 $dVoucherdiscount = $oVoucher->getDiscountValue($dPrice);
01085
01086 if ($dVoucherdiscount > 0) {
01087
01088 if ($oVoucher->getDiscountType() == 'absolute') {
01089 $dVatPart = ($dPrice - $dVoucherdiscount) / $dPrice * 100;
01090 } else {
01091 $dVatPart = 100 - $oVoucher->getDiscount();
01092 }
01093
01094 if (!$this->_aDiscountedVats) {
01095 if ($oPriceList = $this->getDiscountProductsPrice()) {
01096 $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
01097 }
01098 }
01099
01100
01101 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
01102 $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
01103 }
01104 }
01105
01106
01107 $this->_oVoucherDiscount->add($dVoucherdiscount);
01108
01109
01110 $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency($dVoucherdiscount, $this->getBasketCurrency());
01111 $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01112
01113
01114 $dPrice = $dPrice - $dVoucherdiscount;
01115
01116
01117 } catch (oxVoucherException $oEx) {
01118
01119
01120 $oVoucher->unMarkAsReserved();
01121 unset($this->_aVouchers[$sVoucherId]);
01122
01123
01124 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01125 }
01126 }
01127 }
01128 }
01129 }
01130
01134 protected function _applyDiscounts()
01135 {
01136
01137 $dDiscountedSum = $this->_getDiscountedProductsSum();
01138
01139 $oUtils = oxRegistry::getUtils();
01140 $dVatSum = 0;
01141 foreach ($this->_aDiscountedVats as $dVat) {
01142 $dVatSum += $oUtils->fRound($dVat, $this->_oCurrency);
01143 }
01144
01145 $oNotDiscounted = $this->getNotDiscountProductsPrice();
01146
01147 if ($this->isCalculationModeNetto()) {
01148
01149 $this->setNettoSum($this->getProductsPrice()->getSum());
01150 $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedSum + $dVatSum);
01151 } else {
01152
01153 $this->setNettoSum($oNotDiscounted->getSum() + $dDiscountedSum - $dVatSum);
01154 $this->setBruttoSum($this->getProductsPrice()->getSum(false));
01155 }
01156 }
01157
01163 public function isPriceViewModeNetto()
01164 {
01165 $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
01166 $oUser = $this->getBasketUser();
01167 if ($oUser) {
01168 $blResult = $oUser->isPriceViewModeNetto();
01169 }
01170
01171 return $blResult;
01172 }
01173
01179 protected function _getPriceObject()
01180 {
01181 $oPrice = oxNew('oxPrice');
01182
01183 if ($this->isCalculationModeNetto()) {
01184 $oPrice->setNettoPriceMode();
01185 } else {
01186 $oPrice->setBruttoPriceMode();
01187 }
01188
01189 return $oPrice;
01190 }
01191
01195 protected function _calcBasketDiscount()
01196 {
01197
01198 $this->_aDiscounts = array();
01199
01200
01201 $dOldPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto());
01202
01203
01204 if ($this->_oTotalDiscount !== null && isset($this->_isForOrderRecalculation) && $this->_isForOrderRecalculation) {
01205
01206 $oTotalPrice = $this->getTotalDiscount();
01207 $oDiscount = oxNew('oxDiscount');
01208 $oDiscount->oxdiscount__oxaddsum = new oxField($oTotalPrice->getPrice());
01209 $oDiscount->oxdiscount__oxaddsumtype = new oxField('abs');
01210 $aDiscounts[] = $oDiscount;
01211 } else {
01212
01213 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts($this, $this->getBasketUser());
01214 }
01215
01216 if ($oPriceList = $this->getDiscountProductsPrice()) {
01217 $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
01218 }
01219
01220 foreach ($aDiscounts as $oDiscount) {
01221
01222
01223 $oStdDiscount = $oDiscount->getSimpleDiscount();
01224
01225
01226 if ($oDiscount->oxdiscount__oxaddsumtype->value == 'itm') {
01227 continue;
01228 }
01229
01230
01231 $oStdDiscount->dDiscount = $oDiscount->getAbsValue($dOldPrice);
01232
01233 $dVatPart = 100 - $oDiscount->getPercentage($dOldPrice);
01234
01235
01236 if ($dOldPrice < $oStdDiscount->dDiscount) {
01237 $oStdDiscount->dDiscount = $dOldPrice;
01238 $dVatPart = 0;
01239 }
01240
01241
01242 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
01243 $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
01244 }
01245
01246
01247 if ($oStdDiscount->dDiscount != 0) {
01248 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01249
01250 $dOldPrice = $dOldPrice - $oStdDiscount->dDiscount;
01251 }
01252 }
01253 }
01254
01258 protected function _calcBasketTotalDiscount()
01259 {
01260 if ($this->_oTotalDiscount === null || (!$this->isAdmin())) {
01261
01262 $this->_oTotalDiscount = $this->_getPriceObject();
01263
01264 if (is_array($this->_aDiscounts)) {
01265 foreach ($this->_aDiscounts as $oDiscount) {
01266
01267
01268 if ($oDiscount->sType == 'itm') {
01269 continue;
01270 }
01271
01272
01273 $this->_oTotalDiscount->add($oDiscount->dDiscount);
01274 }
01275 }
01276 }
01277 }
01278
01287 protected function _calcBasketWrapping()
01288 {
01289 $oWrappingPrices = oxNew('oxPriceList');
01290
01291 foreach ($this->_aBasketContents as $oBasketItem) {
01292
01293 if (($oWrapping = $oBasketItem->getWrapping())) {
01294
01295 $oWrappingPrice = $oWrapping->getWrappingPrice($oBasketItem->getAmount());
01296 $oWrappingPrice->setVat($oBasketItem->getPrice()->getVat());
01297
01298 $oWrappingPrices->addToPriceList($oWrappingPrice);
01299 }
01300 }
01301
01302 if ($oWrappingPrices->getCount()) {
01303 $oWrappingCost = oxNew('oxPrice');
01304 $oWrappingCost = $oWrappingPrices->calculateToPrice();
01305 }
01306
01307 return $oWrappingCost;
01308 }
01309
01318 protected function _calcBasketGiftCard()
01319 {
01320 $oGiftCardPrice = oxNew('oxPrice');
01321
01322 if ($this->getConfig()->getConfigParam('blWrappingVatOnTop')) {
01323 $oGiftCardPrice->setNettoPriceMode();
01324 } else {
01325 $oGiftCardPrice->setBruttoPriceMode();
01326 }
01327
01328 $dVATPercent = $this->getAdditionalServicesVatPercent();
01329
01330 $oGiftCardPrice->setVat($dVATPercent);
01331
01332
01333 if (($oCard = $this->getCard())) {
01334 if ($dVATPercent !== null) {
01335 $oCard->setWrappingVat($dVATPercent);
01336 }
01337 $oGiftCardPrice->addPrice($oCard->getWrappingPrice());
01338 }
01339
01340 return $oGiftCardPrice;
01341 }
01342
01349 protected function _calcPaymentCost()
01350 {
01351
01352 $oPaymentPrice = oxNew('oxPrice');
01353
01354
01355 if (($this->_sPaymentId = $this->getPaymentId())) {
01356
01357 $oPayment = oxNew('oxPayment');
01358 $oPayment->load($this->_sPaymentId);
01359
01360 $oPayment->calculate($this);
01361 $oPaymentPrice = $oPayment->getPrice();
01362 }
01363
01364 return $oPaymentPrice;
01365 }
01366
01373 protected function _calcTsProtectionCost()
01374 {
01375 if (($this->getTsProductId())) {
01376 $oTsProtection = oxNew('oxtsprotection');
01377 $oTsProduct = $oTsProtection->getTsProduct($this->getTsProductId());
01378 $oProtectionPrice = $oTsProduct->getPrice();
01379 $oProtectionPrice->setVat($this->getAdditionalServicesVatPercent());
01380 } else {
01381 $oProtectionPrice = oxNew('oxPrice');
01382 }
01383
01384 return $oProtectionPrice;
01385 }
01386
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 if (!$this->isEnabled()) {
01422 return;
01423 }
01424
01425 if ($blForceUpdate) {
01426 $this->onUpdate();
01427 }
01428
01429 if (!($this->_blUpdateNeeded || $blForceUpdate)) {
01430 return;
01431 }
01432
01433 $this->_aCosts = array();
01434
01435
01436 $this->_save();
01437
01438
01439 $this->_clearBundles();
01440
01441
01442 $this->_addBundles();
01443
01444
01445 if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
01446 $this->getSession()->getBasketReservations()->reserveBasket($this);
01447 }
01448
01449
01450 $this->_calcItemsPrice();
01451
01452
01453 $this->_calcBasketDiscount();
01454
01455
01456 $this->_calcBasketTotalDiscount();
01457
01458
01459 $this->_calcVoucherDiscount();
01460
01461
01462 $this->_applyDiscounts();
01463
01464
01465
01466 $this->setCost('oxdelivery', $this->_calcDeliveryCost());
01467
01468
01469 $this->setCost('oxwrapping', $this->_calcBasketWrapping());
01470
01471 $this->setCost('oxgiftcard', $this->_calcBasketGiftCard());
01472
01473
01474 $this->setCost('oxpayment', $this->_calcPaymentCost());
01475
01476
01477 $this->setCost('oxtsprotection', $this->_calcTsProtectionCost());
01478
01479
01480 $this->_calcTotalPrice();
01481
01482
01483 $this->formatDiscount();
01484
01485
01486 $this->afterUpdate();
01487 }
01488
01492 public function onUpdate()
01493 {
01494 $this->_blUpdateNeeded = true;
01495 }
01496
01500 public function afterUpdate()
01501 {
01502 $this->_blUpdateNeeded = false;
01503 }
01504
01512 public function getBasketSummary()
01513 {
01514 if ($this->_blUpdateNeeded || $this->_aBasketSummary === null) {
01515 $this->_aBasketSummary = new stdclass();
01516 $this->_aBasketSummary->aArticles = array();
01517 $this->_aBasketSummary->aCategories = array();
01518 $this->_aBasketSummary->iArticleCount = 0;
01519 $this->_aBasketSummary->dArticlePrice = 0;
01520 $this->_aBasketSummary->dArticleDiscountablePrice = 0;
01521 }
01522
01523 if (!$this->isEnabled()) {
01524 return $this->_aBasketSummary;
01525 }
01526
01527 $myConfig = $this->getConfig();
01528 foreach ($this->_aBasketContents as $oBasketItem) {
01529 if (!$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false)) {
01530 $aCatIds = $oArticle->getCategoryIds();
01531
01532 $dPrice = 0;
01533 $dDiscountablePrice = 0;
01534 if (($oPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this))) {
01535 $dPrice = $oPrice->getPrice();
01536 if (!$oArticle->skipDiscounts()) {
01537 $dDiscountablePrice = $dPrice;
01538 }
01539 }
01540
01541 foreach ($aCatIds as $sCatId) {
01542 if (!isset($this->_aBasketSummary->aCategories[$sCatId])) {
01543 $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
01544 }
01545
01546 $this->_aBasketSummary->aCategories[$sCatId]->dPrice += $dPrice * $oBasketItem->getAmount();
01547 $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01548 $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
01549 $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
01550 }
01551
01552
01553 if (($sParentId = $oArticle->getParentId()) && $myConfig->getConfigParam('blVariantParentBuyable')) {
01554 if (!isset($this->_aBasketSummary->aArticles[$sParentId])) {
01555 $this->_aBasketSummary->aArticles[$sParentId] = 0;
01556 }
01557 $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
01558 }
01559
01560 if (!isset($this->_aBasketSummary->aArticles[$oBasketItem->getProductId()])) {
01561 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
01562 }
01563
01564 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
01565 $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
01566 $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
01567 $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01568 }
01569 }
01570
01571 return $this->_aBasketSummary;
01572 }
01573
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
01621 public function removeVoucher($sVoucherId)
01622 {
01623
01624 if (isset($this->_aVouchers[$sVoucherId])) {
01625
01626 $oVoucher = oxNew('oxVoucher');
01627 $oVoucher->load($sVoucherId);
01628
01629 $oVoucher->unMarkAsReserved();
01630
01631
01632 unset($this->_aVouchers[$sVoucherId]);
01633 $this->onUpdate();
01634 }
01635
01636 }
01637
01641 public function resetUserInfo()
01642 {
01643 $this->setPayment(null);
01644 $this->setShipping(null);
01645 }
01646
01650 protected function formatDiscount()
01651 {
01652
01653
01654 $this->aDiscounts = $this->getDiscounts();
01655 if (count($this->aDiscounts) > 0) {
01656 $oLang = oxRegistry::getLang();
01657 foreach ($this->aDiscounts as $oDiscount) {
01658 $oDiscount->fDiscount = $oLang->formatCurrency($oDiscount->dDiscount, $this->getBasketCurrency());
01659 }
01660 }
01661 }
01662
01670 protected function _canSaveBasket()
01671 {
01672 return $this->isSaveToDataBaseEnabled();
01673 }
01674
01680 public function load()
01681 {
01682 $oUser = $this->getBasketUser();
01683 if (!$oUser) {
01684 return;
01685 }
01686
01687 $oBasket = $oUser->getBasket('savedbasket');
01688
01689
01690 $aSavedItems = $oBasket->getItems();
01691 foreach ($aSavedItems as $oItem) {
01692 try {
01693 $oSelList = $oItem->getSelList();
01694
01695 $this->addToBasket($oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true);
01696 } catch (oxArticleException $oEx) {
01697
01698 }
01699 }
01700 }
01701
01705 protected function _save()
01706 {
01707 if ($this->isSaveToDataBaseEnabled()) {
01708
01709 if ($oUser = $this->getBasketUser()) {
01710
01711
01712 $oSavedBasket = $oUser->getBasket('savedbasket');
01713 $oSavedBasket->delete();
01714
01715
01716 foreach ($this->_aBasketContents as $oBasketItem) {
01717
01718 if (!$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle()) {
01719 $oSavedBasket->addItemToBasket($oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams());
01720 }
01721 }
01722 }
01723 }
01724 }
01725
01731 protected function _deleteSavedBasket()
01732 {
01733
01734 if ($oUser = $this->getBasketUser()) {
01735 $oUser->getBasket('savedbasket')->delete();
01736 }
01737
01738
01739 if ($this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
01740 $this->setBasketRootCatId(null);
01741 }
01742 }
01743
01749 protected function _findDelivCountry()
01750 {
01751 $myConfig = $this->getConfig();
01752 $oUser = $this->getBasketUser();
01753
01754 $sDeliveryCountry = null;
01755
01756 if (!$oUser) {
01757
01758 $aHomeCountry = $myConfig->getConfigParam('aHomeCountry');
01759 if ($myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn') && is_array($aHomeCountry)) {
01760 $sDeliveryCountry = current($aHomeCountry);
01761 }
01762 } else {
01763
01764
01765 if ($sCountryId = $myConfig->getGlobalParameter('delcountryid')) {
01766 $sDeliveryCountry = $sCountryId;
01767 } elseif ($sAddressId = oxRegistry::getSession()->getVariable('deladrid')) {
01768
01769 $oDeliveryAddress = oxNew('oxAddress');
01770 if ($oDeliveryAddress->load($sAddressId)) {
01771 $sDeliveryCountry = $oDeliveryAddress->oxaddress__oxcountryid->value;
01772 }
01773 }
01774
01775
01776 if (!$sDeliveryCountry) {
01777 $sDeliveryCountry = $oUser->oxuser__oxcountryid->value;
01778 }
01779 }
01780
01781 return $sDeliveryCountry;
01782 }
01783
01787 public function deleteBasket()
01788 {
01789 $this->_aBasketContents = array();
01790 $this->getSession()->delBasket();
01791
01792 if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
01793 $this->getSession()->getBasketReservations()->discardReservations();
01794 }
01795
01796
01797 $this->_deleteSavedBasket();
01798 }
01799
01805 public function setPayment($sPaymentId = null)
01806 {
01807 $this->_sPaymentId = $sPaymentId;
01808 }
01809
01815 public function getPaymentId()
01816 {
01817 if (!$this->_sPaymentId) {
01818 $this->_sPaymentId = oxRegistry::getSession()->getVariable('paymentid');
01819 }
01820
01821 return $this->_sPaymentId;
01822 }
01823
01829 public function setShipping($sShippingSetId = null)
01830 {
01831 $this->_sShippingSetId = $sShippingSetId;
01832 oxRegistry::getSession()->setVariable('sShipSet', $sShippingSetId);
01833 }
01834
01840 public function setDeliveryPrice($oShippingPrice = null)
01841 {
01842 $this->_oDeliveryPrice = $oShippingPrice;
01843 }
01844
01850 public function getShippingId()
01851 {
01852 if (!$this->_sShippingSetId) {
01853 $this->_sShippingSetId = oxRegistry::getSession()->getVariable('sShipSet');
01854 }
01855
01856 $sActPaymentId = $this->getPaymentId();
01857
01858 if (!$this->_sShippingSetId && $sActPaymentId != 'oxempty') {
01859 $oUser = $this->getUser();
01860
01861
01862 list(, $sActShipSet) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData(null, $oUser, $this);
01863
01864 $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ($oUser ? null : 'oxidstandard');
01865 } elseif (!$this->isAdmin() && $sActPaymentId == 'oxempty') {
01866
01867 $this->_sShippingSetId = null;
01868 }
01869
01870 return $this->_sShippingSetId;
01871 }
01872
01878 public function getBasketArticles()
01879 {
01880 $aBasketArticles = array();
01881
01882 foreach ($this->_aBasketContents as $sItemKey => $oBasketItem) {
01883 try {
01884 $oProduct = $oBasketItem->getArticle(true);
01885
01886 if ($this->getConfig()->getConfigParam('bl_perfLoadSelectLists')) {
01887
01888 $aSelList = $oBasketItem->getSelList();
01889 if (is_array($aSelList) && ($aSelectlist = $oProduct->getSelectLists($sItemKey))) {
01890 reset($aSelList);
01891 while (list($conkey, $iSel) = each($aSelList)) {
01892 $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01893 $aSelectlist[$conkey][$iSel]->selected = 1;
01894 }
01895 $oProduct->setSelectlist($aSelectlist);
01896 }
01897 }
01898 } catch (oxNoArticleException $oEx) {
01899 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
01900 $this->removeItem($sItemKey);
01901 $this->calculateBasket(true);
01902 continue;
01903 } catch (oxArticleInputException $oEx) {
01904 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
01905 $this->removeItem($sItemKey);
01906 $this->calculateBasket(true);
01907 continue;
01908 }
01909
01910 $aBasketArticles[$sItemKey] = $oProduct;
01911 }
01912
01913 return $aBasketArticles;
01914 }
01915
01921 public function getDiscountProductsPrice()
01922 {
01923 return $this->_oDiscountProductsPriceList;
01924 }
01925
01931 public function getProductsPrice()
01932 {
01933 if (is_null($this->_oProductsPriceList)) {
01934 $this->_oProductsPriceList = oxNew('oxPriceList');
01935 }
01936
01937 return $this->_oProductsPriceList;
01938 }
01939
01945 public function getPrice()
01946 {
01947 if (is_null($this->_oPrice)) {
01948 $this->setPrice(oxNew('oxPrice'));
01949 }
01950
01951 return $this->_oPrice;
01952 }
01953
01959 public function setPrice($oPrice)
01960 {
01961 $this->_oPrice = $oPrice;
01962 }
01963
01964
01971 public function getOrderId()
01972 {
01973 return $this->_sOrderId;
01974 }
01975
01981 public function setOrderId($sId)
01982 {
01983 $this->_sOrderId = $sId;
01984 }
01985
01994 public function getCosts($sId = null)
01995 {
01996
01997 if ($sId) {
01998 return isset($this->_aCosts[$sId]) ? $this->_aCosts[$sId] : null;
01999 }
02000
02001 return $this->_aCosts;
02002 }
02003
02009 public function getVouchers()
02010 {
02011 return $this->_aVouchers;
02012 }
02013
02019 public function getProductsCount()
02020 {
02021 return $this->_iProductsCnt;
02022 }
02023
02029 public function getItemsCount()
02030 {
02031 return $this->_dItemsCnt;
02032 }
02033
02039 public function getWeight()
02040 {
02041 return $this->_dWeight;
02042 }
02043
02049 public function getContents()
02050 {
02051 return $this->_aBasketContents;
02052 }
02053
02061 public function getProductVats($blFormatCurrency = true)
02062 {
02063 if (!$this->_oNotDiscountedProductsPriceList) {
02064 return array();
02065 }
02066
02067 $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo($this->isCalculationModeNetto());
02068
02069 $oUtils = oxRegistry::getUtils();
02070 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
02071 if (!isset($aVats[$sKey])) {
02072 $aVats[$sKey] = 0;
02073 }
02074
02075 $aVats[$sKey] += $oUtils->fRound($dVat, $this->_oCurrency);
02076 }
02077
02078 if ($blFormatCurrency) {
02079 $oLang = oxRegistry::getLang();
02080 foreach ($aVats as $sKey => $dVat) {
02081 $aVats[$sKey] = $oLang->formatCurrency($dVat, $this->getBasketCurrency());
02082 }
02083 }
02084
02085 return $aVats;
02086 }
02087
02093 public function setCardMessage($sMessage)
02094 {
02095 $this->_sCardMessage = $sMessage;
02096 }
02097
02103 public function getCardMessage()
02104 {
02105 return $this->_sCardMessage;
02106 }
02107
02113 public function setCardId($sCardId)
02114 {
02115 $this->_sCardId = $sCardId;
02116 }
02117
02123 public function getCardId()
02124 {
02125 return $this->_sCardId;
02126 }
02127
02133 public function getCard()
02134 {
02135 $oCard = null;
02136 if ($sCardId = $this->getCardId()) {
02137 $oCard = oxNew('oxWrapping');
02138 $oCard->load($sCardId);
02139 $oCard->setWrappingVat($this->getAdditionalServicesVatPercent());
02140 }
02141
02142 return $oCard;
02143 }
02144
02150 public function getTotalDiscount()
02151 {
02152 return $this->_oTotalDiscount;
02153 }
02154
02160 public function getDiscounts()
02161 {
02162 if ($this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
02163 return null;
02164 }
02165
02166 return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
02167 }
02168
02174 public function getVoucherDiscount()
02175 {
02176 if ($this->getConfig()->getConfigParam('bl_showVouchers')) {
02177 return $this->_oVoucherDiscount;
02178 }
02179
02180 return null;
02181 }
02182
02188 public function setBasketCurrency($oCurrency)
02189 {
02190 $this->_oCurrency = $oCurrency;
02191 }
02192
02198 public function getBasketCurrency()
02199 {
02200 if ($this->_oCurrency === null) {
02201 $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
02202 }
02203
02204 return $this->_oCurrency;
02205 }
02206
02212 public function setSkipVouchersChecking($blSkipChecking = null)
02213 {
02214 $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
02215 }
02216
02222 public function hasSkipedDiscount()
02223 {
02224 return $this->_blSkipDiscounts;
02225 }
02226
02232 public function setSkipDiscounts($blSkip)
02233 {
02234 $this->_blSkipDiscounts = $blSkip;
02235 }
02236
02244 public function getProductsNetPrice()
02245 {
02246 return oxRegistry::getLang()->formatCurrency($this->getNettoSum(), $this->getBasketCurrency());
02247 }
02248
02256 public function getFProductsPrice()
02257 {
02258 return oxRegistry::getLang()->formatCurrency($this->getBruttoSum(), $this->getBasketCurrency());
02259 }
02260
02268 public function getDelCostVatPercent()
02269 {
02270 return $this->getCosts('oxdelivery')->getVat();
02271 }
02272
02280 public function getDelCostVat()
02281 {
02282 $dDelVAT = $this->getCosts('oxdelivery')->getVatValue();
02283
02284
02285 if ($dDelVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForDelivery')) {
02286 return oxRegistry::getLang()->formatCurrency($dDelVAT, $this->getBasketCurrency());
02287 }
02288
02289 return false;
02290 }
02291
02299 public function getDelCostNet()
02300 {
02301 $oConfig = $this->getConfig();
02302
02303
02304 if ($oConfig->getConfigParam('blShowVATForDelivery') && ($this->getBasketUser() || $oConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
02305 $dNetPrice = $this->getCosts('oxdelivery')->getNettoPrice();
02306 if ($dNetPrice > 0) {
02307 return oxRegistry::getLang()->formatCurrency($dNetPrice, $this->getBasketCurrency());
02308 }
02309 }
02310
02311 return false;
02312 }
02313
02321 public function getPayCostVatPercent()
02322 {
02323 return $this->getCosts('oxpayment')->getVat();
02324 }
02325
02333 public function getPayCostVat()
02334 {
02335 $dPayVAT = $this->getCosts('oxpayment')->getVatValue();
02336
02337
02338 if ($dPayVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02339 return oxRegistry::getLang()->formatCurrency($dPayVAT, $this->getBasketCurrency());
02340 }
02341
02342 return false;
02343 }
02344
02352 public function getPayCostNet()
02353 {
02354
02355 if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02356 $oPaymentCost = $this->getCosts('oxpayment');
02357 if ($oPaymentCost && $oPaymentCost->getNettoPrice()) {
02358 return oxRegistry::getLang()->formatCurrency($this->getCosts('oxpayment')->getNettoPrice(), $this->getBasketCurrency());
02359 }
02360 }
02361
02362 return false;
02363 }
02364
02372 public function getPaymentCosts()
02373 {
02374 $oPaymentCost = $this->getCosts('oxpayment');
02375 if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
02376 return $oPaymentCost->getBruttoPrice();
02377 }
02378 }
02379
02385 public function getPaymentCost()
02386 {
02387 return $this->getCosts('oxpayment');
02388 }
02389
02397 public function getFPaymentCosts()
02398 {
02399 $oPaymentCost = $this->getCosts('oxpayment');
02400 if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
02401 return oxRegistry::getLang()->formatCurrency($oPaymentCost->getBruttoPrice(), $this->getBasketCurrency());
02402 }
02403
02404 return false;
02405 }
02406
02412 public function getVoucherDiscValue()
02413 {
02414 if ($this->getVoucherDiscount()) {
02415 return $this->getVoucherDiscount()->getBruttoPrice();
02416 }
02417
02418 return false;
02419 }
02420
02428 public function getFVoucherDiscountValue()
02429 {
02430 if ($oVoucherDiscount = $this->getVoucherDiscount()) {
02431 if ($oVoucherDiscount->getBruttoPrice()) {
02432 return oxRegistry::getLang()->formatCurrency($oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency());
02433 }
02434 }
02435
02436 return false;
02437 }
02438
02439
02447 public function getWrappCostVatPercent()
02448 {
02449 return $this->getCosts('oxwrapping')->getVat();
02450 }
02451
02452
02460 public function getGiftCardCostVatPercent()
02461 {
02462 return $this->getCosts('oxgiftcard')->getVat();
02463 }
02464
02472 public function getWrappCostVat()
02473 {
02474
02475 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02476 $oPrice = $this->getCosts('oxwrapping');
02477
02478 if ($oPrice && $oPrice->getVatValue() > 0) {
02479 return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
02480 }
02481 }
02482
02483 return false;
02484 }
02485
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
02514 public function getFWrappingCosts()
02515 {
02516 $oPrice = $this->getCosts('oxwrapping');
02517
02518 if ($oPrice && $oPrice->getBruttoPrice()) {
02519 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02520 }
02521
02522 return false;
02523 }
02524
02530 public function getWrappingCost()
02531 {
02532 return $this->getCosts('oxwrapping');
02533 }
02534
02542 public function getGiftCardCostVat()
02543 {
02544
02545 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02546 $oPrice = $this->getCosts('oxgiftcard');
02547
02548 if ($oPrice && $oPrice->getVatValue() > 0) {
02549 return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
02550 }
02551 }
02552
02553 return false;
02554
02555 }
02556
02564 public function getGiftCardCostNet()
02565 {
02566
02567 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02568 $oPrice = $this->getCosts('oxgiftcard');
02569
02570 if ($oPrice && $oPrice->getNettoPrice() > 0) {
02571 return oxRegistry::getLang()->formatCurrency($oPrice->getNettoPrice(), $this->getBasketCurrency());
02572 }
02573 }
02574
02575 return false;
02576 }
02577
02585 public function getFGiftCardCosts()
02586 {
02587 $oPrice = $this->getCosts('oxgiftcard');
02588
02589 if ($oPrice && $oPrice->getBruttoPrice()) {
02590 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02591 }
02592
02593 return false;
02594 }
02595
02601 public function getGiftCardCost()
02602 {
02603 return $this->getCosts('oxgiftcard');
02604 }
02605
02613 public function getFPrice()
02614 {
02615 return oxRegistry::getLang()->formatCurrency($this->getPrice()->getBruttoPrice(), $this->getBasketCurrency());
02616 }
02617
02625 public function getFDeliveryCosts()
02626 {
02627 $oPrice = $this->getCosts('oxdelivery');
02628
02629 if ($oPrice && ($this->getBasketUser() || $this->getConfig()->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
02630 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02631 }
02632
02633 return false;
02634 }
02635
02643 public function getDeliveryCosts()
02644 {
02645 if ($oDeliveryCost = $this->getCosts('oxdelivery')) {
02646 return $oDeliveryCost->getBruttoPrice();
02647 }
02648
02649 return false;
02650 }
02651
02657 public function getDeliveryCost()
02658 {
02659 return $this->getCosts('oxdelivery');
02660 }
02661
02667 public function setTotalDiscount($dDiscount)
02668 {
02669 $this->_oTotalDiscount = oxNew('oxPrice');
02670 $this->_oTotalDiscount->setBruttoPriceMode();
02671 $this->_oTotalDiscount->add($dDiscount);
02672 }
02673
02680 public function getPriceForPayment()
02681 {
02682 $dPrice = $this->getDiscountedProductsBruttoPrice();
02683
02684 if ($oPriceList = $this->getNotDiscountProductsPrice()) {
02685 $dPrice += $oPriceList->getBruttoSum();
02686 }
02687
02688
02689 if ($oDeliveryPrice = $this->_aCosts['oxdelivery']) {
02690 $dPrice += $oDeliveryPrice->getBruttoPrice();
02691 }
02692
02693 return $dPrice;
02694 }
02695
02696
02702 public function _getDiscountedProductsSum()
02703 {
02704 if ($oProductsPrice = $this->getDiscountProductsPrice()) {
02705 $dPrice = $oProductsPrice->getSum($this->isCalculationModeNetto());
02706 }
02707
02708
02709 if ($oPrice = $this->getTotalDiscount()) {
02710 $dPrice -= $oPrice->getPrice();
02711 }
02712
02713 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02714 $dPrice -= $oVoucherPrice->getPrice();
02715 }
02716
02717 return $dPrice;
02718 }
02719
02725 public function getTotalDiscountSum()
02726 {
02727 $dPrice = 0;
02728
02729 if ($oPrice = $this->getTotalDiscount()) {
02730 $dPrice += $oPrice->getPrice();
02731 }
02732
02733 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02734 $dPrice += $oVoucherPrice->getPrice();
02735 }
02736
02737 return $dPrice;
02738 }
02739
02745 public function getDiscountedProductsBruttoPrice()
02746 {
02747 if ($oProductsPrice = $this->getDiscountProductsPrice()) {
02748 $dPrice = $oProductsPrice->getBruttoSum();
02749 }
02750
02751
02752 if ($oPrice = $this->getTotalDiscount()) {
02753 $dPrice -= $oPrice->getBruttoPrice();
02754 }
02755
02756 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02757 $dPrice -= $oVoucherPrice->getBruttoPrice();
02758 }
02759
02760 return $dPrice;
02761 }
02762
02768 public function isBelowMinOrderPrice()
02769 {
02770 $blIsBelowMinOrderPrice = false;
02771 $sConfValue = $this->getConfig()->getConfigParam('iMinOrderPrice');
02772 if (is_numeric($sConfValue) && $this->getProductsCount()) {
02773 $dMinOrderPrice = oxPrice::getPriceInActCurrency(( double ) $sConfValue);
02774 $dNotDiscountedProductPrice = 0;
02775 if ($oPrice = $this->getNotDiscountProductsPrice()) {
02776 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02777 }
02778 $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02779 }
02780
02781 return $blIsBelowMinOrderPrice;
02782
02783 }
02784
02793 public function getArtStockInBasket($sArtId, $sExpiredArtId = null)
02794 {
02795 $dArtStock = 0;
02796 foreach ($this->_aBasketContents as $sItemKey => $oOrderArticle) {
02797 if ($oOrderArticle && ($sExpiredArtId == null || $sExpiredArtId != $sItemKey)) {
02798 if ($oOrderArticle->getArticle(true)->getId() == $sArtId) {
02799 $dArtStock += $oOrderArticle->getAmount();
02800 }
02801 }
02802 }
02803
02804 return $dArtStock;
02805 }
02806
02814 public function canAddProductToBasket($sProductId)
02815 {
02816 $blCanAdd = null;
02817
02818
02819 if ($this->_sBasketCategoryId === null) {
02820 $oCat = null;
02821
02822
02823 if ($oView = $this->getConfig()->getActiveView()) {
02824 if ($oCat = $oView->getActiveCategory()) {
02825 if (!$this->_isProductInRootCategory($sProductId, $oCat->oxcategories__oxrootid->value)) {
02826 $oCat = null;
02827 } else {
02828 $blCanAdd = true;
02829 }
02830 }
02831 }
02832
02833
02834 if (!$oCat) {
02835 $oProduct = oxNew("oxArticle");
02836 if ($oProduct->load($sProductId)) {
02837 $oCat = $oProduct->getCategory();
02838 }
02839 }
02840
02841
02842 if ($oCat) {
02843 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02844 }
02845 }
02846
02847
02848 if ($blCanAdd === null) {
02849 $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory($sProductId, $this->getBasketRootCatId()) : true;
02850 }
02851
02852 return $blCanAdd;
02853 }
02854
02863 protected function _isProductInRootCategory($sProductId, $sRootCatId)
02864 {
02865 $sO2CTable = getViewName('oxobject2category');
02866 $sCatTable = getViewName('oxcategories');
02867
02868 $oDb = oxDb::getDb();
02869 $sParentId = $oDb->getOne("select oxparentid from oxarticles where oxid = " . $oDb->quote($sProductId));
02870 $sProductId = $sParentId ? $sParentId : $sProductId;
02871
02872 $sQ = "select 1 from {$sO2CTable}
02873 left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02874 where {$sO2CTable}.oxobjectid = " . $oDb->quote($sProductId) . " and
02875 {$sCatTable}.oxrootid = " . $oDb->quote($sRootCatId);
02876
02877 return (bool) $oDb->getOne($sQ);
02878 }
02879
02885 public function setBasketRootCatId($sRoot)
02886 {
02887 $this->_sBasketCategoryId = $sRoot;
02888 }
02889
02895 public function getBasketRootCatId()
02896 {
02897 return $this->_sBasketCategoryId;
02898 }
02899
02905 public function setCatChangeWarningState($blShow)
02906 {
02907 $this->_blShowCatChangeWarning = $blShow;
02908 }
02909
02915 public function showCatChangeWarning()
02916 {
02917 return $this->_blShowCatChangeWarning;
02918 }
02919
02925 public function setTsProductId($sProductId)
02926 {
02927 $this->_sTsProductId = $sProductId;
02928 }
02929
02935 public function getTsProductId()
02936 {
02937 return $this->_sTsProductId;
02938 }
02939
02947 public function getFTsProtectionCosts()
02948 {
02949 $oProtectionCost = $this->getCosts('oxtsprotection');
02950 if ($oProtectionCost && $oProtectionCost->getBruttoPrice()) {
02951 return oxRegistry::getLang()->formatCurrency($oProtectionCost->getBruttoPrice(), $this->getBasketCurrency());
02952 }
02953
02954 return false;
02955 }
02956
02964 public function getTsProtectionVatPercent()
02965 {
02966 return $this->getCosts('oxtsprotection')->getVat();
02967 }
02968
02976 public function getTsProtectionVat()
02977 {
02978 $dProtectionVAT = $this->getCosts('oxtsprotection')->getVatValue();
02979
02980 if ($dProtectionVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02981 return oxRegistry::getLang()->formatCurrency($dProtectionVAT, $this->getBasketCurrency());
02982 }
02983
02984 return false;
02985 }
02986
02994 public function getTsProtectionNet()
02995 {
02996
02997 if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02998 return oxRegistry::getLang()->formatCurrency($this->getCosts('oxtsprotection')->getNettoPrice(), $this->getBasketCurrency());
02999 }
03000
03001 return false;
03002 }
03003
03011 public function getTsProtectionCosts()
03012 {
03013 $oProtection = $this->getCosts('oxtsprotection');
03014 if ($oProtection) {
03015 return $oProtection->getBruttoPrice();
03016 }
03017
03018 return false;
03019 }
03020
03026 public function getTrustedShopProtectionCost()
03027 {
03028 return $this->getCosts('oxtsprotection');
03029 }
03030
03031
03037 public function getNotDiscountProductsPrice()
03038 {
03039 return $this->_oNotDiscountedProductsPriceList;
03040 }
03041
03053 protected function _addedNewItem($sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId)
03054 {
03055 if (!$blOverride) {
03056 $this->_blNewITemAdded = null;
03057 oxRegistry::getSession()->setVariable("blAddedNewItem", true);
03058 }
03059 }
03060
03064 public function __wakeUp()
03065 {
03066 $this->_blNewITemAdded = null;
03067 $this->_isCalculationModeNetto = null;
03068 }
03069
03075 public function isNewItemAdded()
03076 {
03077 if ($this->_blNewITemAdded == null) {
03078 $this->_blNewITemAdded = (bool) oxRegistry::getSession()->getVariable("blAddedNewItem");
03079 oxRegistry::getSession()->deleteVariable("blAddedNewItem");
03080 }
03081
03082 return $this->_blNewITemAdded;
03083 }
03084
03090 public function hasDownloadableProducts()
03091 {
03092 $this->_blDownloadableProducts = false;
03094 foreach ($this->_aBasketContents as $oBasketItem) {
03095 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->isDownloadable()) {
03096 $this->_blDownloadableProducts = true;
03097 break;
03098 }
03099 }
03100
03101 return $this->_blDownloadableProducts;
03102 }
03103
03109 public function hasArticlesWithIntangibleAgreement()
03110 {
03111 $blHasArticlesWithIntangibleAgreement = false;
03112
03114 foreach ($this->_aBasketContents as $oBasketItem) {
03115 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasIntangibleAgreement()) {
03116 $blHasArticlesWithIntangibleAgreement = true;
03117 break;
03118 }
03119 }
03120
03121 return $blHasArticlesWithIntangibleAgreement;
03122 }
03123
03129 public function hasArticlesWithDownloadableAgreement()
03130 {
03131 $blHasArticlesWithIntangibleAgreement = false;
03132
03134 foreach ($this->_aBasketContents as $oBasketItem) {
03135 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasDownloadableAgreement()) {
03136 $blHasArticlesWithIntangibleAgreement = true;
03137 break;
03138 }
03139 }
03140
03141 return $blHasArticlesWithIntangibleAgreement;
03142 }
03143
03149 public function getMinOrderPrice()
03150 {
03151 return oxPrice::getPriceInActCurrency($this->getConfig()->getConfigParam('iMinOrderPrice'));
03152 }
03153
03159 public function getTsInsuredSum()
03160 {
03161 return $this->getPrice()->getBruttoPrice() - $this->getCosts('oxtsprotection')->getBruttoPrice();
03162 }
03163 }