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 }
00763 }
00764 }
00765
00766 }
00767
00771 protected function _calcItemsPrice()
00772 {
00773
00774 $this->setSkipDiscounts(false);
00775 $this->_iProductsCnt = 0;
00776 $this->_dItemsCnt = 0;
00777 $this->_dWeight = 0;
00778
00779 $this->_oProductsPriceList = oxNew('oxpricelist');
00780 $this->_oDiscountProductsPriceList = oxNew('oxpricelist');
00781 $this->_oNotDiscountedProductsPriceList = oxNew('oxpricelist');
00782
00783 $oDiscountList = oxRegistry::get("oxDiscountList");
00784
00785 foreach ($this->_aBasketContents as $oBasketItem) {
00786 $this->_iProductsCnt++;
00787 $this->_dItemsCnt += $oBasketItem->getAmount();
00788 $this->_dWeight += $oBasketItem->getWeight();
00789
00790 if (!$oBasketItem->isDiscountArticle() && ($oArticle = $oBasketItem->getArticle(true))) {
00791
00792 $oBasketPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this);
00793 $oBasketItem->setRegularUnitPrice(clone $oBasketPrice);
00794
00795 if (!$oArticle->skipDiscounts() && $this->canCalcDiscounts()) {
00796
00797 $aDiscounts = $oDiscountList->getBasketItemDiscounts($oArticle, $this, $this->getBasketUser());
00798 reset($aDiscounts);
00799 foreach ($aDiscounts as $oDiscount) {
00800 $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
00801 }
00802 $oBasketPrice->calculateDiscount();
00803 } else {
00804 $oBasketItem->setSkipDiscounts(true);
00805 $this->setSkipDiscounts(true);
00806 }
00807
00808 $oBasketItem->setPrice($oBasketPrice);
00809 $this->_oProductsPriceList->addToPriceList($oBasketItem->getPrice());
00810
00811
00812 if (!$oArticle->skipDiscounts()) {
00813
00814 $this->_oDiscountProductsPriceList->addToPriceList($oBasketItem->getPrice());
00815 } else {
00816 $this->_oNotDiscountedProductsPriceList->addToPriceList($oBasketItem->getPrice());
00817 $oBasketItem->setSkipDiscounts(true);
00818 $this->setSkipDiscounts(true);
00819 }
00820 } elseif ($oBasketItem->isBundle()) {
00821
00822 $oPrice = oxNew("oxprice");
00823 $oBasketItem->setPrice($oPrice);
00824 }
00825 }
00826 }
00827
00833 public function setDiscountCalcMode($blCalcDiscounts)
00834 {
00835 $this->_blCalcDiscounts = $blCalcDiscounts;
00836 }
00837
00843 public function canCalcDiscounts()
00844 {
00845 return $this->_blCalcDiscounts;
00846 }
00847
00857 protected function _mergeDiscounts($aDiscounts, $aItemDiscounts)
00858 {
00859 foreach ($aItemDiscounts as $sKey => $oDiscount) {
00860
00861 if (array_key_exists($sKey, $aDiscounts)) {
00862 $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
00863 } else {
00864 $aDiscounts[$sKey] = $oDiscount;
00865 }
00866 }
00867
00868 return $aDiscounts;
00869 }
00870
00876 protected function _calcDeliveryCost()
00877 {
00878 if ($this->_oDeliveryPrice !== null) {
00879 return $this->_oDeliveryPrice;
00880 }
00881 $myConfig = $this->getConfig();
00882 $oDeliveryPrice = oxNew('oxprice');
00883
00884 if ($this->getConfig()->getConfigParam('blDeliveryVatOnTop')) {
00885 $oDeliveryPrice->setNettoPriceMode();
00886 } else {
00887 $oDeliveryPrice->setBruttoPriceMode();
00888 }
00889
00890
00891 $oUser = $this->getBasketUser();
00892
00893 if (!$oUser && !$myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn')) {
00894 return $oDeliveryPrice;
00895 }
00896
00897 $fDelVATPercent = $this->getAdditionalServicesVatPercent();
00898 $oDeliveryPrice->setVat($fDelVATPercent);
00899
00900
00901 if ($myConfig->getConfigParam('bl_perfLoadDelivery')) {
00902 $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList(
00903 $this,
00904 $oUser,
00905 $this->_findDelivCountry(),
00906 $this->getShippingId()
00907 );
00908
00909 if (count($aDeliveryList) > 0) {
00910 foreach ($aDeliveryList as $oDelivery) {
00911
00912 if ($myConfig->getConfigParam('iDebug') == 5) {
00913 echo("DelCost : " . $oDelivery->oxdelivery__oxtitle->value . "<br>");
00914 }
00915 $oDeliveryPrice->addPrice($oDelivery->getDeliveryPrice($fDelVATPercent));
00916 }
00917 }
00918 }
00919
00920 return $oDeliveryPrice;
00921 }
00922
00928 public function getBasketUser()
00929 {
00930 if ($this->_oUser == null) {
00931 return $this->getUser();
00932 }
00933
00934 return $this->_oUser;
00935 }
00936
00942 public function setBasketUser($oUser)
00943 {
00944 $this->_oUser = $oUser;
00945 }
00946
00947
00953 public function getMostUsedVatPercent()
00954 {
00955 if ($this->_oProductsPriceList) {
00956 return $this->_oProductsPriceList->getMostUsedVatPercent();
00957 }
00958 }
00959
00965 public function getAdditionalServicesVatPercent()
00966 {
00967 if ($this->_oProductsPriceList) {
00968 if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
00969 return $this->_oProductsPriceList->getProportionalVatPercent();
00970 } else {
00971 return $this->_oProductsPriceList->getMostUsedVatPercent();
00972 }
00973 }
00974 }
00975
00981 public function isProportionalCalculationOn()
00982 {
00983 if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
00984 return true;
00985 }
00986
00987 return false;
00988 }
00989
00990
00991
00995 protected function _calcTotalPrice()
00996 {
00997
00998 $dPrice = $this->_dBruttoSum;
00999
01000 $oTotalPrice = oxNew('oxPrice');
01001 $oTotalPrice->setBruttoPriceMode();
01002 $oTotalPrice->setPrice($dPrice);
01003
01004
01005 if ($dPrice && !$this->isCalculationModeNetto()) {
01006
01007
01008 $oTotalPrice->subtract($this->_oTotalDiscount->getBruttoPrice());
01009
01010
01011 if ($oVoucherDisc = $this->getVoucherDiscount()) {
01012 $oTotalPrice->subtract($oVoucherDisc->getBruttoPrice());
01013 }
01014 }
01015
01016
01017 if (isset($this->_aCosts['oxdelivery'])) {
01018 $oTotalPrice->add($this->_aCosts['oxdelivery']->getBruttoPrice());
01019 }
01020
01021
01022 if (isset($this->_aCosts['oxwrapping'])) {
01023 $oTotalPrice->add($this->_aCosts['oxwrapping']->getBruttoPrice());
01024 }
01025 if (isset($this->_aCosts['oxgiftcard'])) {
01026 $oTotalPrice->add($this->_aCosts['oxgiftcard']->getBruttoPrice());
01027 }
01028
01029
01030 if (isset($this->_aCosts['oxpayment'])) {
01031 $oTotalPrice->add($this->_aCosts['oxpayment']->getBruttoPrice());
01032 }
01033
01034
01035 if (isset($this->_aCosts['oxtsprotection'])) {
01036 $oTotalPrice->add($this->_aCosts['oxtsprotection']->getBruttoPrice());
01037 }
01038
01039 $this->setPrice($oTotalPrice);
01040 }
01041
01047 public function setVoucherDiscount($dDiscount)
01048 {
01049 $this->_oVoucherDiscount = oxNew('oxPrice');
01050 $this->_oVoucherDiscount->setBruttoPriceMode();
01051 $this->_oVoucherDiscount->add($dDiscount);
01052 }
01053
01057 protected function _calcVoucherDiscount()
01058 {
01059 if ($this->getConfig()->getConfigParam('bl_showVouchers') && ($this->_oVoucherDiscount === null || ($this->_blUpdateNeeded && !$this->isAdmin()))) {
01060
01061 $this->_oVoucherDiscount = $this->_getPriceObject();
01062
01063
01064 $dPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto()) - $this->_oTotalDiscount->getPrice();
01065
01066
01067 if (count($this->_aVouchers)) {
01068 $oLang = oxRegistry::getLang();
01069 foreach ($this->_aVouchers as $sVoucherId => $oStdVoucher) {
01070 $oVoucher = oxNew('oxvoucher');
01071 try {
01072 $oVoucher->load($oStdVoucher->sVoucherId);
01073
01074 if (!$this->_blSkipVouchersAvailabilityChecking) {
01075 $oVoucher->checkBasketVoucherAvailability($this->_aVouchers, $dPrice);
01076 $oVoucher->checkUserAvailability($this->getBasketUser());
01077 }
01078
01079
01080 $dVoucherdiscount = $oVoucher->getDiscountValue($dPrice);
01081
01082 if ($dVoucherdiscount > 0) {
01083
01084 if ($oVoucher->getDiscountType() == 'absolute') {
01085 $dVatPart = ($dPrice - $dVoucherdiscount) / $dPrice * 100;
01086 } else {
01087 $dVatPart = 100 - $oVoucher->getDiscount();
01088 }
01089
01090 if (!$this->_aDiscountedVats) {
01091 if ($oPriceList = $this->getDiscountProductsPrice()) {
01092 $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
01093 }
01094 }
01095
01096
01097 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
01098 $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
01099 }
01100 }
01101
01102
01103 $this->_oVoucherDiscount->add($dVoucherdiscount);
01104
01105
01106 $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency($dVoucherdiscount, $this->getBasketCurrency());
01107 $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
01108
01109
01110 $dPrice = $dPrice - $dVoucherdiscount;
01111
01112
01113 } catch (oxVoucherException $oEx) {
01114
01115
01116 $oVoucher->unMarkAsReserved();
01117 unset($this->_aVouchers[$sVoucherId]);
01118
01119
01120 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01121 }
01122 }
01123 }
01124 }
01125 }
01126
01130 protected function _applyDiscounts()
01131 {
01132
01133 $dDiscountedSum = $this->_getDiscountedProductsSum();
01134
01135 $oUtils = oxRegistry::getUtils();
01136 $dVatSum = 0;
01137 foreach ($this->_aDiscountedVats as $dVat) {
01138 $dVatSum += $oUtils->fRound($dVat, $this->_oCurrency);
01139 }
01140
01141 $oNotDiscounted = $this->getNotDiscountProductsPrice();
01142
01143 if ($this->isCalculationModeNetto()) {
01144
01145 $this->setNettoSum($this->getProductsPrice()->getSum());
01146 $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedSum + $dVatSum);
01147 } else {
01148
01149 $this->setNettoSum($oNotDiscounted->getSum() + $dDiscountedSum - $dVatSum);
01150 $this->setBruttoSum($this->getProductsPrice()->getSum(false));
01151 }
01152 }
01153
01159 public function isPriceViewModeNetto()
01160 {
01161 $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
01162 $oUser = $this->getBasketUser();
01163 if ($oUser) {
01164 $blResult = $oUser->isPriceViewModeNetto();
01165 }
01166
01167 return $blResult;
01168 }
01169
01175 protected function _getPriceObject()
01176 {
01177 $oPrice = oxNew('oxPrice');
01178
01179 if ($this->isCalculationModeNetto()) {
01180 $oPrice->setNettoPriceMode();
01181 } else {
01182 $oPrice->setBruttoPriceMode();
01183 }
01184
01185 return $oPrice;
01186 }
01187
01191 protected function _calcBasketDiscount()
01192 {
01193
01194 $this->_aDiscounts = array();
01195
01196
01197 $dOldPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto());
01198
01199
01200 if ($this->_oTotalDiscount !== null && isset($this->_isForOrderRecalculation) && $this->_isForOrderRecalculation) {
01201
01202 $oTotalPrice = $this->getTotalDiscount();
01203 $oDiscount = oxNew('oxDiscount');
01204 $oDiscount->oxdiscount__oxaddsum = new oxField($oTotalPrice->getPrice());
01205 $oDiscount->oxdiscount__oxaddsumtype = new oxField('abs');
01206 $aDiscounts[] = $oDiscount;
01207 } else {
01208
01209 $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts($this, $this->getBasketUser());
01210 }
01211
01212 if ($oPriceList = $this->getDiscountProductsPrice()) {
01213 $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
01214 }
01215
01216 foreach ($aDiscounts as $oDiscount) {
01217
01218
01219 $oStdDiscount = $oDiscount->getSimpleDiscount();
01220
01221
01222 if ($oDiscount->oxdiscount__oxaddsumtype->value == 'itm') {
01223 continue;
01224 }
01225
01226
01227 $oStdDiscount->dDiscount = $oDiscount->getAbsValue($dOldPrice);
01228
01229 $dVatPart = 100 - $oDiscount->getPercentage($dOldPrice);
01230
01231
01232 if ($dOldPrice < $oStdDiscount->dDiscount) {
01233 $oStdDiscount->dDiscount = $dOldPrice;
01234 $dVatPart = 0;
01235 }
01236
01237
01238 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
01239 $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
01240 }
01241
01242
01243 if ($oStdDiscount->dDiscount != 0) {
01244 $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
01245
01246 $dOldPrice = $dOldPrice - $oStdDiscount->dDiscount;
01247 }
01248 }
01249 }
01250
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
01389 public function setCost($sCostName, $oPrice = null)
01390 {
01391 $this->_aCosts[$sCostName] = $oPrice;
01392 }
01393
01402 public function calculateBasket($blForceUpdate = false)
01403 {
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 if (!$this->isEnabled()) {
01418 return;
01419 }
01420
01421 if ($blForceUpdate) {
01422 $this->onUpdate();
01423 }
01424
01425 if (!($this->_blUpdateNeeded || $blForceUpdate)) {
01426 return;
01427 }
01428
01429 $this->_aCosts = array();
01430
01431
01432 $this->_save();
01433
01434
01435 $this->_clearBundles();
01436
01437
01438 $this->_addBundles();
01439
01440
01441 if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
01442 $this->getSession()->getBasketReservations()->reserveBasket($this);
01443 }
01444
01445
01446 $this->_calcItemsPrice();
01447
01448
01449 $this->_calcBasketDiscount();
01450
01451
01452 $this->_calcBasketTotalDiscount();
01453
01454
01455 $this->_calcVoucherDiscount();
01456
01457
01458 $this->_applyDiscounts();
01459
01460
01461
01462 $this->setCost('oxdelivery', $this->_calcDeliveryCost());
01463
01464
01465 $this->setCost('oxwrapping', $this->_calcBasketWrapping());
01466
01467 $this->setCost('oxgiftcard', $this->_calcBasketGiftCard());
01468
01469
01470 $this->setCost('oxpayment', $this->_calcPaymentCost());
01471
01472
01473 $this->setCost('oxtsprotection', $this->_calcTsProtectionCost());
01474
01475
01476 $this->_calcTotalPrice();
01477
01478
01479 $this->formatDiscount();
01480
01481
01482 $this->afterUpdate();
01483 }
01484
01488 public function onUpdate()
01489 {
01490 $this->_blUpdateNeeded = true;
01491 }
01492
01496 public function afterUpdate()
01497 {
01498 $this->_blUpdateNeeded = false;
01499 }
01500
01508 public function getBasketSummary()
01509 {
01510 if ($this->_blUpdateNeeded || $this->_aBasketSummary === null) {
01511 $this->_aBasketSummary = new stdclass();
01512 $this->_aBasketSummary->aArticles = array();
01513 $this->_aBasketSummary->aCategories = array();
01514 $this->_aBasketSummary->iArticleCount = 0;
01515 $this->_aBasketSummary->dArticlePrice = 0;
01516 $this->_aBasketSummary->dArticleDiscountablePrice = 0;
01517 }
01518
01519 if (!$this->isEnabled()) {
01520 return $this->_aBasketSummary;
01521 }
01522
01523 $myConfig = $this->getConfig();
01524 foreach ($this->_aBasketContents as $oBasketItem) {
01525 if (!$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false)) {
01526 $aCatIds = $oArticle->getCategoryIds();
01527
01528 $dPrice = 0;
01529 $dDiscountablePrice = 0;
01530 if (($oPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this))) {
01531 $dPrice = $oPrice->getPrice();
01532 if (!$oArticle->skipDiscounts()) {
01533 $dDiscountablePrice = $dPrice;
01534 }
01535 }
01536
01537 foreach ($aCatIds as $sCatId) {
01538 if (!isset($this->_aBasketSummary->aCategories[$sCatId])) {
01539 $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
01540 }
01541
01542 $this->_aBasketSummary->aCategories[$sCatId]->dPrice += $dPrice * $oBasketItem->getAmount();
01543 $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01544 $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
01545 $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
01546 }
01547
01548
01549 if (($sParentId = $oArticle->getParentId()) && $myConfig->getConfigParam('blVariantParentBuyable')) {
01550 if (!isset($this->_aBasketSummary->aArticles[$sParentId])) {
01551 $this->_aBasketSummary->aArticles[$sParentId] = 0;
01552 }
01553 $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
01554 }
01555
01556 if (!isset($this->_aBasketSummary->aArticles[$oBasketItem->getProductId()])) {
01557 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
01558 }
01559
01560 $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
01561 $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
01562 $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
01563 $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
01564 }
01565 }
01566
01567 return $this->_aBasketSummary;
01568 }
01569
01579 public function addVoucher($sVoucherId)
01580 {
01581
01582
01583 $dPrice = 0;
01584 if ($this->_oDiscountProductsPriceList) {
01585 $dPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto());
01586 }
01587
01588 try {
01589
01590 $oVoucher = oxNew('oxvoucher');
01591
01592 if (!$this->_blSkipVouchersAvailabilityChecking) {
01593 $oVoucher->getVoucherByNr($sVoucherId, $this->_aVouchers, true);
01594 $oVoucher->checkVoucherAvailability($this->_aVouchers, $dPrice);
01595 $oVoucher->checkUserAvailability($this->getBasketUser());
01596 $oVoucher->markAsReserved();
01597 } else {
01598 $oVoucher->load($sVoucherId);
01599 }
01600
01601
01602 $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
01603 } catch (oxVoucherException $oEx) {
01604
01605
01606 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
01607 }
01608
01609 $this->onUpdate();
01610 }
01611
01617 public function removeVoucher($sVoucherId)
01618 {
01619
01620 if (isset($this->_aVouchers[$sVoucherId])) {
01621
01622 $oVoucher = oxNew('oxVoucher');
01623 $oVoucher->load($sVoucherId);
01624
01625 $oVoucher->unMarkAsReserved();
01626
01627
01628 unset($this->_aVouchers[$sVoucherId]);
01629 $this->onUpdate();
01630 }
01631
01632 }
01633
01637 public function resetUserInfo()
01638 {
01639 $this->setPayment(null);
01640 $this->setShipping(null);
01641 }
01642
01646 protected function formatDiscount()
01647 {
01648
01649
01650 $this->aDiscounts = $this->getDiscounts();
01651 if (count($this->aDiscounts) > 0) {
01652 $oLang = oxRegistry::getLang();
01653 foreach ($this->aDiscounts as $oDiscount) {
01654 $oDiscount->fDiscount = $oLang->formatCurrency($oDiscount->dDiscount, $this->getBasketCurrency());
01655 }
01656 }
01657 }
01658
01666 protected function _canSaveBasket()
01667 {
01668 return $this->isSaveToDataBaseEnabled();
01669 }
01670
01676 public function load()
01677 {
01678 $oUser = $this->getBasketUser();
01679 if (!$oUser) {
01680 return;
01681 }
01682
01683 $oBasket = $oUser->getBasket('savedbasket');
01684
01685
01686 $aSavedItems = $oBasket->getItems();
01687 foreach ($aSavedItems as $oItem) {
01688 try {
01689 $oSelList = $oItem->getSelList();
01690
01691 $this->addToBasket($oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true);
01692 } catch (oxArticleException $oEx) {
01693
01694 }
01695 }
01696 }
01697
01701 protected function _save()
01702 {
01703 if ($this->isSaveToDataBaseEnabled()) {
01704
01705 if ($oUser = $this->getBasketUser()) {
01706
01707
01708 $oSavedBasket = $oUser->getBasket('savedbasket');
01709 $oSavedBasket->delete();
01710
01711
01712 foreach ($this->_aBasketContents as $oBasketItem) {
01713
01714 if (!$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle()) {
01715 $oSavedBasket->addItemToBasket($oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams());
01716 }
01717 }
01718 }
01719 }
01720 }
01721
01727 protected function _deleteSavedBasket()
01728 {
01729
01730 if ($oUser = $this->getBasketUser()) {
01731 $oUser->getBasket('savedbasket')->delete();
01732 }
01733
01734
01735 if ($this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
01736 $this->setBasketRootCatId(null);
01737 }
01738 }
01739
01745 protected function _findDelivCountry()
01746 {
01747 $myConfig = $this->getConfig();
01748 $oUser = $this->getBasketUser();
01749
01750 $sDeliveryCountry = null;
01751
01752 if (!$oUser) {
01753
01754 $aHomeCountry = $myConfig->getConfigParam('aHomeCountry');
01755 if ($myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn') && is_array($aHomeCountry)) {
01756 $sDeliveryCountry = current($aHomeCountry);
01757 }
01758 } else {
01759
01760
01761 if ($sCountryId = $myConfig->getGlobalParameter('delcountryid')) {
01762 $sDeliveryCountry = $sCountryId;
01763 } elseif ($sAddressId = oxRegistry::getSession()->getVariable('deladrid')) {
01764
01765 $oDeliveryAddress = oxNew('oxAddress');
01766 if ($oDeliveryAddress->load($sAddressId)) {
01767 $sDeliveryCountry = $oDeliveryAddress->oxaddress__oxcountryid->value;
01768 }
01769 }
01770
01771
01772 if (!$sDeliveryCountry) {
01773 $sDeliveryCountry = $oUser->oxuser__oxcountryid->value;
01774 }
01775 }
01776
01777 return $sDeliveryCountry;
01778 }
01779
01783 public function deleteBasket()
01784 {
01785 $this->_aBasketContents = array();
01786 $this->getSession()->delBasket();
01787
01788 if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
01789 $this->getSession()->getBasketReservations()->discardReservations();
01790 }
01791
01792
01793 $this->_deleteSavedBasket();
01794 }
01795
01801 public function setPayment($sPaymentId = null)
01802 {
01803 $this->_sPaymentId = $sPaymentId;
01804 }
01805
01811 public function getPaymentId()
01812 {
01813 if (!$this->_sPaymentId) {
01814 $this->_sPaymentId = oxRegistry::getSession()->getVariable('paymentid');
01815 }
01816
01817 return $this->_sPaymentId;
01818 }
01819
01825 public function setShipping($sShippingSetId = null)
01826 {
01827 $this->_sShippingSetId = $sShippingSetId;
01828 oxRegistry::getSession()->setVariable('sShipSet', $sShippingSetId);
01829 }
01830
01836 public function setDeliveryPrice($oShippingPrice = null)
01837 {
01838 $this->_oDeliveryPrice = $oShippingPrice;
01839 }
01840
01846 public function getShippingId()
01847 {
01848 if (!$this->_sShippingSetId) {
01849 $this->_sShippingSetId = oxRegistry::getSession()->getVariable('sShipSet');
01850 }
01851
01852 $sActPaymentId = $this->getPaymentId();
01853
01854 if (!$this->_sShippingSetId && $sActPaymentId != 'oxempty') {
01855 $oUser = $this->getUser();
01856
01857
01858 list(, $sActShipSet) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData(null, $oUser, $this);
01859
01860 $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ($oUser ? null : 'oxidstandard');
01861 } elseif (!$this->isAdmin() && $sActPaymentId == 'oxempty') {
01862
01863 $this->_sShippingSetId = null;
01864 }
01865
01866 return $this->_sShippingSetId;
01867 }
01868
01874 public function getBasketArticles()
01875 {
01876 $aBasketArticles = array();
01877
01878 foreach ($this->_aBasketContents as $sItemKey => $oBasketItem) {
01879 try {
01880 $oProduct = $oBasketItem->getArticle(true);
01881
01882 if ($this->getConfig()->getConfigParam('bl_perfLoadSelectLists')) {
01883
01884 $aSelList = $oBasketItem->getSelList();
01885 if (is_array($aSelList) && ($aSelectlist = $oProduct->getSelectLists($sItemKey))) {
01886 reset($aSelList);
01887 while (list($conkey, $iSel) = each($aSelList)) {
01888 $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
01889 $aSelectlist[$conkey][$iSel]->selected = 1;
01890 }
01891 $oProduct->setSelectlist($aSelectlist);
01892 }
01893 }
01894 } catch (oxNoArticleException $oEx) {
01895 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
01896 $this->removeItem($sItemKey);
01897 $this->calculateBasket(true);
01898 continue;
01899 } catch (oxArticleInputException $oEx) {
01900 oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
01901 $this->removeItem($sItemKey);
01902 $this->calculateBasket(true);
01903 continue;
01904 }
01905
01906 $aBasketArticles[$sItemKey] = $oProduct;
01907 }
01908
01909 return $aBasketArticles;
01910 }
01911
01917 public function getDiscountProductsPrice()
01918 {
01919 return $this->_oDiscountProductsPriceList;
01920 }
01921
01927 public function getProductsPrice()
01928 {
01929 if (is_null($this->_oProductsPriceList)) {
01930 $this->_oProductsPriceList = oxNew('oxPriceList');
01931 }
01932
01933 return $this->_oProductsPriceList;
01934 }
01935
01941 public function getPrice()
01942 {
01943 if (is_null($this->_oPrice)) {
01944 $this->setPrice(oxNew('oxPrice'));
01945 }
01946
01947 return $this->_oPrice;
01948 }
01949
01955 public function setPrice($oPrice)
01956 {
01957 $this->_oPrice = $oPrice;
01958 }
01959
01960
01967 public function getOrderId()
01968 {
01969 return $this->_sOrderId;
01970 }
01971
01977 public function setOrderId($sId)
01978 {
01979 $this->_sOrderId = $sId;
01980 }
01981
01990 public function getCosts($sId = null)
01991 {
01992
01993 if ($sId) {
01994 return isset($this->_aCosts[$sId]) ? $this->_aCosts[$sId] : null;
01995 }
01996
01997 return $this->_aCosts;
01998 }
01999
02005 public function getVouchers()
02006 {
02007 return $this->_aVouchers;
02008 }
02009
02015 public function getProductsCount()
02016 {
02017 return $this->_iProductsCnt;
02018 }
02019
02025 public function getItemsCount()
02026 {
02027 return $this->_dItemsCnt;
02028 }
02029
02035 public function getWeight()
02036 {
02037 return $this->_dWeight;
02038 }
02039
02045 public function getContents()
02046 {
02047 return $this->_aBasketContents;
02048 }
02049
02057 public function getProductVats($blFormatCurrency = true)
02058 {
02059 if (!$this->_oNotDiscountedProductsPriceList) {
02060 return array();
02061 }
02062
02063 $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo($this->isCalculationModeNetto());
02064
02065 $oUtils = oxRegistry::getUtils();
02066 foreach ($this->_aDiscountedVats as $sKey => $dVat) {
02067 if (!isset($aVats[$sKey])) {
02068 $aVats[$sKey] = 0;
02069 }
02070
02071 $aVats[$sKey] += $oUtils->fRound($dVat, $this->_oCurrency);
02072 }
02073
02074 if ($blFormatCurrency) {
02075 $oLang = oxRegistry::getLang();
02076 foreach ($aVats as $sKey => $dVat) {
02077 $aVats[$sKey] = $oLang->formatCurrency($dVat, $this->getBasketCurrency());
02078 }
02079 }
02080
02081 return $aVats;
02082 }
02083
02089 public function setCardMessage($sMessage)
02090 {
02091 $this->_sCardMessage = $sMessage;
02092 }
02093
02099 public function getCardMessage()
02100 {
02101 return $this->_sCardMessage;
02102 }
02103
02109 public function setCardId($sCardId)
02110 {
02111 $this->_sCardId = $sCardId;
02112 }
02113
02119 public function getCardId()
02120 {
02121 return $this->_sCardId;
02122 }
02123
02129 public function getCard()
02130 {
02131 $oCard = null;
02132 if ($sCardId = $this->getCardId()) {
02133 $oCard = oxNew('oxWrapping');
02134 $oCard->load($sCardId);
02135 $oCard->setWrappingVat($this->getAdditionalServicesVatPercent());
02136 }
02137
02138 return $oCard;
02139 }
02140
02146 public function getTotalDiscount()
02147 {
02148 return $this->_oTotalDiscount;
02149 }
02150
02156 public function getDiscounts()
02157 {
02158 if ($this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
02159 return null;
02160 }
02161
02162 return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
02163 }
02164
02170 public function getVoucherDiscount()
02171 {
02172 if ($this->getConfig()->getConfigParam('bl_showVouchers')) {
02173 return $this->_oVoucherDiscount;
02174 }
02175
02176 return null;
02177 }
02178
02184 public function setBasketCurrency($oCurrency)
02185 {
02186 $this->_oCurrency = $oCurrency;
02187 }
02188
02194 public function getBasketCurrency()
02195 {
02196 if ($this->_oCurrency === null) {
02197 $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
02198 }
02199
02200 return $this->_oCurrency;
02201 }
02202
02208 public function setSkipVouchersChecking($blSkipChecking = null)
02209 {
02210 $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
02211 }
02212
02218 public function hasSkipedDiscount()
02219 {
02220 return $this->_blSkipDiscounts;
02221 }
02222
02228 public function setSkipDiscounts($blSkip)
02229 {
02230 $this->_blSkipDiscounts = $blSkip;
02231 }
02232
02240 public function getProductsNetPrice()
02241 {
02242 return oxRegistry::getLang()->formatCurrency($this->getNettoSum(), $this->getBasketCurrency());
02243 }
02244
02252 public function getFProductsPrice()
02253 {
02254 return oxRegistry::getLang()->formatCurrency($this->getBruttoSum(), $this->getBasketCurrency());
02255 }
02256
02264 public function getDelCostVatPercent()
02265 {
02266 return $this->getCosts('oxdelivery')->getVat();
02267 }
02268
02276 public function getDelCostVat()
02277 {
02278 $dDelVAT = $this->getCosts('oxdelivery')->getVatValue();
02279
02280
02281 if ($dDelVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForDelivery')) {
02282 return oxRegistry::getLang()->formatCurrency($dDelVAT, $this->getBasketCurrency());
02283 }
02284
02285 return false;
02286 }
02287
02295 public function getDelCostNet()
02296 {
02297 $oConfig = $this->getConfig();
02298
02299
02300 if ($oConfig->getConfigParam('blShowVATForDelivery') && ($this->getBasketUser() || $oConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
02301 $dNetPrice = $this->getCosts('oxdelivery')->getNettoPrice();
02302 if ($dNetPrice > 0) {
02303 return oxRegistry::getLang()->formatCurrency($dNetPrice, $this->getBasketCurrency());
02304 }
02305 }
02306
02307 return false;
02308 }
02309
02317 public function getPayCostVatPercent()
02318 {
02319 return $this->getCosts('oxpayment')->getVat();
02320 }
02321
02329 public function getPayCostVat()
02330 {
02331 $dPayVAT = $this->getCosts('oxpayment')->getVatValue();
02332
02333
02334 if ($dPayVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02335 return oxRegistry::getLang()->formatCurrency($dPayVAT, $this->getBasketCurrency());
02336 }
02337
02338 return false;
02339 }
02340
02348 public function getPayCostNet()
02349 {
02350
02351 if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02352 $oPaymentCost = $this->getCosts('oxpayment');
02353 if ($oPaymentCost && $oPaymentCost->getNettoPrice()) {
02354 return oxRegistry::getLang()->formatCurrency($this->getCosts('oxpayment')->getNettoPrice(), $this->getBasketCurrency());
02355 }
02356 }
02357
02358 return false;
02359 }
02360
02368 public function getPaymentCosts()
02369 {
02370 $oPaymentCost = $this->getCosts('oxpayment');
02371 if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
02372 return $oPaymentCost->getBruttoPrice();
02373 }
02374 }
02375
02381 public function getPaymentCost()
02382 {
02383 return $this->getCosts('oxpayment');
02384 }
02385
02393 public function getFPaymentCosts()
02394 {
02395 $oPaymentCost = $this->getCosts('oxpayment');
02396 if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
02397 return oxRegistry::getLang()->formatCurrency($oPaymentCost->getBruttoPrice(), $this->getBasketCurrency());
02398 }
02399
02400 return false;
02401 }
02402
02408 public function getVoucherDiscValue()
02409 {
02410 if ($this->getVoucherDiscount()) {
02411 return $this->getVoucherDiscount()->getBruttoPrice();
02412 }
02413
02414 return false;
02415 }
02416
02424 public function getFVoucherDiscountValue()
02425 {
02426 if ($oVoucherDiscount = $this->getVoucherDiscount()) {
02427 if ($oVoucherDiscount->getBruttoPrice()) {
02428 return oxRegistry::getLang()->formatCurrency($oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency());
02429 }
02430 }
02431
02432 return false;
02433 }
02434
02435
02443 public function getWrappCostVatPercent()
02444 {
02445 return $this->getCosts('oxwrapping')->getVat();
02446 }
02447
02448
02456 public function getGiftCardCostVatPercent()
02457 {
02458 return $this->getCosts('oxgiftcard')->getVat();
02459 }
02460
02468 public function getWrappCostVat()
02469 {
02470
02471 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02472 $oPrice = $this->getCosts('oxwrapping');
02473
02474 if ($oPrice && $oPrice->getVatValue() > 0) {
02475 return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
02476 }
02477 }
02478
02479 return false;
02480 }
02481
02489 public function getWrappCostNet()
02490 {
02491
02492 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02493 $oPrice = $this->getCosts('oxwrapping');
02494
02495 if ($oPrice && $oPrice->getNettoPrice() > 0) {
02496 return oxRegistry::getLang()->formatCurrency($oPrice->getNettoPrice(), $this->getBasketCurrency());
02497 }
02498 }
02499
02500 return false;
02501 }
02502
02510 public function getFWrappingCosts()
02511 {
02512 $oPrice = $this->getCosts('oxwrapping');
02513
02514 if ($oPrice && $oPrice->getBruttoPrice()) {
02515 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02516 }
02517
02518 return false;
02519 }
02520
02526 public function getWrappingCost()
02527 {
02528 return $this->getCosts('oxwrapping');
02529 }
02530
02538 public function getGiftCardCostVat()
02539 {
02540
02541 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02542 $oPrice = $this->getCosts('oxgiftcard');
02543
02544 if ($oPrice && $oPrice->getVatValue() > 0) {
02545 return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
02546 }
02547 }
02548
02549 return false;
02550
02551 }
02552
02560 public function getGiftCardCostNet()
02561 {
02562
02563 if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
02564 $oPrice = $this->getCosts('oxgiftcard');
02565
02566 if ($oPrice && $oPrice->getNettoPrice() > 0) {
02567 return oxRegistry::getLang()->formatCurrency($oPrice->getNettoPrice(), $this->getBasketCurrency());
02568 }
02569 }
02570
02571 return false;
02572 }
02573
02581 public function getFGiftCardCosts()
02582 {
02583 $oPrice = $this->getCosts('oxgiftcard');
02584
02585 if ($oPrice && $oPrice->getBruttoPrice()) {
02586 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02587 }
02588
02589 return false;
02590 }
02591
02597 public function getGiftCardCost()
02598 {
02599 return $this->getCosts('oxgiftcard');
02600 }
02601
02609 public function getFPrice()
02610 {
02611 return oxRegistry::getLang()->formatCurrency($this->getPrice()->getBruttoPrice(), $this->getBasketCurrency());
02612 }
02613
02621 public function getFDeliveryCosts()
02622 {
02623 $oPrice = $this->getCosts('oxdelivery');
02624
02625 if ($oPrice && ($this->getBasketUser() || $this->getConfig()->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
02626 return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
02627 }
02628
02629 return false;
02630 }
02631
02639 public function getDeliveryCosts()
02640 {
02641 if ($oDeliveryCost = $this->getCosts('oxdelivery')) {
02642 return $oDeliveryCost->getBruttoPrice();
02643 }
02644
02645 return false;
02646 }
02647
02653 public function getDeliveryCost()
02654 {
02655 return $this->getCosts('oxdelivery');
02656 }
02657
02663 public function setTotalDiscount($dDiscount)
02664 {
02665 $this->_oTotalDiscount = oxNew('oxPrice');
02666 $this->_oTotalDiscount->setBruttoPriceMode();
02667 $this->_oTotalDiscount->add($dDiscount);
02668 }
02669
02676 public function getPriceForPayment()
02677 {
02678 $dPrice = $this->getDiscountedProductsBruttoPrice();
02679
02680 if ($oPriceList = $this->getNotDiscountProductsPrice()) {
02681 $dPrice += $oPriceList->getBruttoSum();
02682 }
02683
02684
02685 if ($oDeliveryPrice = $this->_aCosts['oxdelivery']) {
02686 $dPrice += $oDeliveryPrice->getBruttoPrice();
02687 }
02688
02689 return $dPrice;
02690 }
02691
02692
02698 public function _getDiscountedProductsSum()
02699 {
02700 if ($oProductsPrice = $this->getDiscountProductsPrice()) {
02701 $dPrice = $oProductsPrice->getSum($this->isCalculationModeNetto());
02702 }
02703
02704
02705 if ($oPrice = $this->getTotalDiscount()) {
02706 $dPrice -= $oPrice->getPrice();
02707 }
02708
02709 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02710 $dPrice -= $oVoucherPrice->getPrice();
02711 }
02712
02713 return $dPrice;
02714 }
02715
02721 public function getTotalDiscountSum()
02722 {
02723 $dPrice = 0;
02724
02725 if ($oPrice = $this->getTotalDiscount()) {
02726 $dPrice += $oPrice->getPrice();
02727 }
02728
02729 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02730 $dPrice += $oVoucherPrice->getPrice();
02731 }
02732
02733 return $dPrice;
02734 }
02735
02741 public function getDiscountedProductsBruttoPrice()
02742 {
02743 if ($oProductsPrice = $this->getDiscountProductsPrice()) {
02744 $dPrice = $oProductsPrice->getBruttoSum();
02745 }
02746
02747
02748 if ($oPrice = $this->getTotalDiscount()) {
02749 $dPrice -= $oPrice->getBruttoPrice();
02750 }
02751
02752 if ($oVoucherPrice = $this->getVoucherDiscount()) {
02753 $dPrice -= $oVoucherPrice->getBruttoPrice();
02754 }
02755
02756 return $dPrice;
02757 }
02758
02764 public function isBelowMinOrderPrice()
02765 {
02766 $blIsBelowMinOrderPrice = false;
02767 $sConfValue = $this->getConfig()->getConfigParam('iMinOrderPrice');
02768 if (is_numeric($sConfValue) && $this->getProductsCount()) {
02769 $dMinOrderPrice = oxPrice::getPriceInActCurrency(( double ) $sConfValue);
02770 $dNotDiscountedProductPrice = 0;
02771 if ($oPrice = $this->getNotDiscountProductsPrice()) {
02772 $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
02773 }
02774 $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
02775 }
02776
02777 return $blIsBelowMinOrderPrice;
02778
02779 }
02780
02789 public function getArtStockInBasket($sArtId, $sExpiredArtId = null)
02790 {
02791 $dArtStock = 0;
02792 foreach ($this->_aBasketContents as $sItemKey => $oOrderArticle) {
02793 if ($oOrderArticle && ($sExpiredArtId == null || $sExpiredArtId != $sItemKey)) {
02794 if ($oOrderArticle->getArticle(true)->getId() == $sArtId) {
02795 $dArtStock += $oOrderArticle->getAmount();
02796 }
02797 }
02798 }
02799
02800 return $dArtStock;
02801 }
02802
02810 public function canAddProductToBasket($sProductId)
02811 {
02812 $blCanAdd = null;
02813
02814
02815 if ($this->_sBasketCategoryId === null) {
02816 $oCat = null;
02817
02818
02819 if ($oView = $this->getConfig()->getActiveView()) {
02820 if ($oCat = $oView->getActiveCategory()) {
02821 if (!$this->_isProductInRootCategory($sProductId, $oCat->oxcategories__oxrootid->value)) {
02822 $oCat = null;
02823 } else {
02824 $blCanAdd = true;
02825 }
02826 }
02827 }
02828
02829
02830 if (!$oCat) {
02831 $oProduct = oxNew("oxArticle");
02832 if ($oProduct->load($sProductId)) {
02833 $oCat = $oProduct->getCategory();
02834 }
02835 }
02836
02837
02838 if ($oCat) {
02839 $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
02840 }
02841 }
02842
02843
02844 if ($blCanAdd === null) {
02845 $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory($sProductId, $this->getBasketRootCatId()) : true;
02846 }
02847
02848 return $blCanAdd;
02849 }
02850
02859 protected function _isProductInRootCategory($sProductId, $sRootCatId)
02860 {
02861 $sO2CTable = getViewName('oxobject2category');
02862 $sCatTable = getViewName('oxcategories');
02863
02864 $oDb = oxDb::getDb();
02865 $sParentId = $oDb->getOne("select oxparentid from oxarticles where oxid = " . $oDb->quote($sProductId));
02866 $sProductId = $sParentId ? $sParentId : $sProductId;
02867
02868 $sQ = "select 1 from {$sO2CTable}
02869 left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
02870 where {$sO2CTable}.oxobjectid = " . $oDb->quote($sProductId) . " and
02871 {$sCatTable}.oxrootid = " . $oDb->quote($sRootCatId);
02872
02873 return (bool) $oDb->getOne($sQ);
02874 }
02875
02881 public function setBasketRootCatId($sRoot)
02882 {
02883 $this->_sBasketCategoryId = $sRoot;
02884 }
02885
02891 public function getBasketRootCatId()
02892 {
02893 return $this->_sBasketCategoryId;
02894 }
02895
02901 public function setCatChangeWarningState($blShow)
02902 {
02903 $this->_blShowCatChangeWarning = $blShow;
02904 }
02905
02911 public function showCatChangeWarning()
02912 {
02913 return $this->_blShowCatChangeWarning;
02914 }
02915
02921 public function setTsProductId($sProductId)
02922 {
02923 $this->_sTsProductId = $sProductId;
02924 }
02925
02931 public function getTsProductId()
02932 {
02933 return $this->_sTsProductId;
02934 }
02935
02943 public function getFTsProtectionCosts()
02944 {
02945 $oProtectionCost = $this->getCosts('oxtsprotection');
02946 if ($oProtectionCost && $oProtectionCost->getBruttoPrice()) {
02947 return oxRegistry::getLang()->formatCurrency($oProtectionCost->getBruttoPrice(), $this->getBasketCurrency());
02948 }
02949
02950 return false;
02951 }
02952
02960 public function getTsProtectionVatPercent()
02961 {
02962 return $this->getCosts('oxtsprotection')->getVat();
02963 }
02964
02972 public function getTsProtectionVat()
02973 {
02974 $dProtectionVAT = $this->getCosts('oxtsprotection')->getVatValue();
02975
02976 if ($dProtectionVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02977 return oxRegistry::getLang()->formatCurrency($dProtectionVAT, $this->getBasketCurrency());
02978 }
02979
02980 return false;
02981 }
02982
02990 public function getTsProtectionNet()
02991 {
02992
02993 if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
02994 return oxRegistry::getLang()->formatCurrency($this->getCosts('oxtsprotection')->getNettoPrice(), $this->getBasketCurrency());
02995 }
02996
02997 return false;
02998 }
02999
03007 public function getTsProtectionCosts()
03008 {
03009 $oProtection = $this->getCosts('oxtsprotection');
03010 if ($oProtection) {
03011 return $oProtection->getBruttoPrice();
03012 }
03013
03014 return false;
03015 }
03016
03022 public function getTrustedShopProtectionCost()
03023 {
03024 return $this->getCosts('oxtsprotection');
03025 }
03026
03027
03033 public function getNotDiscountProductsPrice()
03034 {
03035 return $this->_oNotDiscountedProductsPriceList;
03036 }
03037
03049 protected function _addedNewItem($sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId)
03050 {
03051 if (!$blOverride) {
03052 $this->_blNewITemAdded = null;
03053 oxRegistry::getSession()->setVariable("blAddedNewItem", true);
03054 }
03055 }
03056
03060 public function __wakeUp()
03061 {
03062 $this->_blNewITemAdded = null;
03063 $this->_isCalculationModeNetto = null;
03064 }
03065
03071 public function isNewItemAdded()
03072 {
03073 if ($this->_blNewITemAdded == null) {
03074 $this->_blNewITemAdded = (bool) oxRegistry::getSession()->getVariable("blAddedNewItem");
03075 oxRegistry::getSession()->deleteVariable("blAddedNewItem");
03076 }
03077
03078 return $this->_blNewITemAdded;
03079 }
03080
03086 public function hasDownloadableProducts()
03087 {
03088 $this->_blDownloadableProducts = false;
03090 foreach ($this->_aBasketContents as $oBasketItem) {
03091 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->isDownloadable()) {
03092 $this->_blDownloadableProducts = true;
03093 break;
03094 }
03095 }
03096
03097 return $this->_blDownloadableProducts;
03098 }
03099
03105 public function hasArticlesWithIntangibleAgreement()
03106 {
03107 $blHasArticlesWithIntangibleAgreement = false;
03108
03110 foreach ($this->_aBasketContents as $oBasketItem) {
03111 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasIntangibleAgreement()) {
03112 $blHasArticlesWithIntangibleAgreement = true;
03113 break;
03114 }
03115 }
03116
03117 return $blHasArticlesWithIntangibleAgreement;
03118 }
03119
03125 public function hasArticlesWithDownloadableAgreement()
03126 {
03127 $blHasArticlesWithIntangibleAgreement = false;
03128
03130 foreach ($this->_aBasketContents as $oBasketItem) {
03131 if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasDownloadableAgreement()) {
03132 $blHasArticlesWithIntangibleAgreement = true;
03133 break;
03134 }
03135 }
03136
03137 return $blHasArticlesWithIntangibleAgreement;
03138 }
03139
03145 public function getMinOrderPrice()
03146 {
03147 return oxPrice::getPriceInActCurrency($this->getConfig()->getConfigParam('iMinOrderPrice'));
03148 }
03149
03155 public function getTsInsuredSum()
03156 {
03157 return $this->getPrice()->getBruttoPrice() - $this->getCosts('oxtsprotection')->getBruttoPrice();
03158 }
03159 }