OXID eShop CE  4.9.6
 All Classes Files Functions Variables Pages
oxbasket.php
Go to the documentation of this file.
1 <?php
2 
7 class oxBasket extends oxSuperCfg
8 {
9 
15  protected $_aBasketContents = array();
16 
22  protected $_iProductsCnt = 0;
23 
29  protected $_dItemsCnt = 0.0;
30 
36  protected $_dWeight = 0.0;
37 
43  protected $_oPrice = null;
44 
50  protected $_isCalculationModeNetto = null;
51 
57  protected $_dNettoSum = null;
58 
64  protected $_dBruttoSum = null;
65 
71  protected $_oProductsPriceList = null;
72 
78  protected $_aDiscounts = array();
79 
85  protected $_aItemDiscounts = array();
86 
92  protected $_sOrderId = null;
93 
99  protected $_aVouchers = array();
100 
106  protected $_aCosts = array();
107 
114 
121 
127  protected $_blUpdateNeeded = true;
128 
134  protected $_aBasketSummary = null;
135 
141  protected $_sPaymentId = null;
142 
148  protected $_sShippingSetId = null;
149 
155  protected $_oUser = null;
156 
162  protected $_oTotalDiscount = null;
163 
169  protected $_oVoucherDiscount = null;
170 
176  protected $_oCurrency = null;
177 
184 
191 
197  protected $_aDiscountedVats = null;
198 
204  protected $_blSkipDiscounts = false;
205 
211  protected $_oDeliveryPrice = null;
212 
218  protected $_blCheckStock = true;
219 
225  protected $_blCalcDiscounts = true;
226 
232  protected $_sBasketCategoryId = null;
233 
239  protected $_blShowCatChangeWarning = false;
240 
246  protected $_sTsProductId = null;
247 
253  protected $_blNewITemAdded = null;
254 
260  protected $_blDownloadableProducts = null;
261 
262 
268  protected $_blSaveToDataBase = null;
269 
275  public function enableSaveToDataBase($blSave = true)
276  {
277  $this->_blSaveToDataBase = $blSave;
278  }
279 
285  public function isSaveToDataBaseEnabled()
286  {
287  if (is_null($this->_blSaveToDataBase)) {
288  $this->_blSaveToDataBase = (bool) !$this->getConfig()->getConfigParam('blPerfNoBasketSaving');
289  }
290 
292  }
293 
294 
300  public function isCalculationModeNetto()
301  {
302  if ($this->_isCalculationModeNetto === null) {
304  }
305 
307  }
308 
314  public function setCalculationModeNetto($blNettoMode = true)
315  {
316  $this->_isCalculationModeNetto = (bool) $blNettoMode;
317  }
318 
324  public function getNettoSum()
325  {
326  return $this->_dNettoSum;
327  }
328 
334  public function getBruttoSum()
335  {
336  return $this->_dBruttoSum;
337  }
338 
344  public function setNettoSum($dNettoSum)
345  {
346  $this->_dNettoSum = $dNettoSum;
347  }
348 
354  public function setBruttoSum($dBruttoSum)
355  {
356  $this->_dBruttoSum = $dBruttoSum;
357  }
358 
364  public function isEnabled()
365  {
366  return !oxRegistry::getUtils()->isSearchEngine();
367  }
368 
376  protected function _changeBasketItemKey($sOldKey, $sNewKey, $value = null)
377  {
378  reset($this->_aBasketContents);
379  $iOldKeyPlace = 0;
380  while (key($this->_aBasketContents) != $sOldKey && next($this->_aBasketContents)) {
381  ++$iOldKeyPlace;
382  }
383  $aNewCopy = array_merge(
384  array_slice($this->_aBasketContents, 0, $iOldKeyPlace, true),
385  array($sNewKey => $value),
386  array_slice($this->_aBasketContents, $iOldKeyPlace + 1, count($this->_aBasketContents) - $iOldKeyPlace, true)
387  );
388  $this->_aBasketContents = $aNewCopy;
389  }
390 
406  public function addToBasket($sProductID, $dAmount, $aSel = null, $aPersParam = null, $blOverride = false, $blBundle = false, $sOldBasketItemId = null)
407  {
408  // enabled ?
409  if (!$this->isEnabled()) {
410  return null;
411  }
412 
413  // basket exclude
414  if ($this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
415  if (!$this->canAddProductToBasket($sProductID)) {
416  $this->setCatChangeWarningState(true);
417 
418  return null;
419  } else {
420  $this->setCatChangeWarningState(false);
421  }
422  }
423 
424  $sItemId = $this->getItemKey($sProductID, $aSel, $aPersParam, $blBundle);
425  if ($sOldBasketItemId && (strcmp($sOldBasketItemId, $sItemId) != 0)) {
426  if (isset($this->_aBasketContents[$sItemId])) {
427  // we are merging, so params will just go to the new key
428  unset($this->_aBasketContents[$sOldBasketItemId]);
429  // do not override stock
430  $blOverride = false;
431  } else {
432  // value is null - means isset will fail and real values will be filled
433  $this->_changeBasketItemKey($sOldBasketItemId, $sItemId);
434  }
435  }
436 
437  // after some checks item must be removed from basket
438  $blRemoveItem = false;
439 
440  // initialling exception storage
441  $oEx = null;
442 
443  if (isset($this->_aBasketContents[$sItemId])) {
444 
445  //updating existing
446  try {
447  // setting stock check status
448  $this->_aBasketContents[$sItemId]->setStockCheckStatus($this->getStockCheckMode());
449  //validate amount
450  //possibly throws exception
451  $this->_aBasketContents[$sItemId]->setAmount($dAmount, $blOverride, $sItemId);
452  } catch (oxOutOfStockException $oEx) {
453  // rethrow later
454  }
455 
456  } else {
457  //inserting new
458  $oBasketItem = oxNew('oxbasketitem');
459  try {
460  $oBasketItem->setStockCheckStatus($this->getStockCheckMode());
461  $oBasketItem->init($sProductID, $dAmount, $aSel, $aPersParam, $blBundle);
462  } catch (oxNoArticleException $oEx) {
463  // in this case that the article does not exist remove the item from the basket by setting its amount to 0
464  //$oBasketItem->dAmount = 0;
465  $blRemoveItem = true;
466 
467  } catch (oxOutOfStockException $oEx) {
468  // rethrow later
469  } catch (oxArticleInputException $oEx) {
470  // rethrow later
471  $blRemoveItem = true;
472  }
473 
474  $this->_aBasketContents[$sItemId] = $oBasketItem;
475  }
476 
477  //in case amount is 0 removing item
478  if ($this->_aBasketContents[$sItemId]->getAmount() == 0 || $blRemoveItem) {
479  $this->removeItem($sItemId);
480  } elseif ($blBundle) {
481  //marking bundles
482  $this->_aBasketContents[$sItemId]->setBundle(true);
483  }
484 
485  //calling update method
486  $this->onUpdate();
487 
488  if ($oEx) {
489  throw $oEx;
490  }
491 
492  // notifying that new basket item was added
493  if (!$blBundle) {
494  $this->_addedNewItem($sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId);
495  }
496 
497  // returning basket item object
498  return $this->_aBasketContents[$sItemId];
499  }
500 
508  public function addOrderArticleToBasket($oOrderArticle)
509  {
510  // adding only if amount > 0
511  if ($oOrderArticle->oxorderarticles__oxamount->value > 0 && !$oOrderArticle->isBundle()) {
512 
513  $this->_isForOrderRecalculation = true;
514  $sItemId = $oOrderArticle->getId();
515 
516  //inserting new
517  $this->_aBasketContents[$sItemId] = oxNew('oxbasketitem');
518  $this->_aBasketContents[$sItemId]->initFromOrderArticle($oOrderArticle);
519  $this->_aBasketContents[$sItemId]->setWrapping($oOrderArticle->oxorderarticles__oxwrapid->value);
520  $this->_aBasketContents[$sItemId]->setBundle($oOrderArticle->isBundle());
521 
522  //calling update method
523  $this->onUpdate();
524 
525  return $this->_aBasketContents[$sItemId];
526  } elseif ($oOrderArticle->isBundle()) {
527  // deleting bundles, they are handled automatically
528  $oOrderArticle->delete();
529  }
530  }
531 
537  public function setStockCheckMode($blCheck)
538  {
539  $this->_blCheckStock = $blCheck;
540  }
541 
547  public function getStockCheckMode()
548  {
549  return $this->_blCheckStock;
550  }
551 
564  public function getItemKey($sProductId, $aSel = null, $aPersParam = null, $blBundle = false, $sAdditionalParam = '')
565  {
566  $aSel = ($aSel != null) ? $aSel : array(0 => '0');
567 
568  $sItemKey = md5($sProductId . '|' . serialize($aSel) . '|' . serialize($aPersParam) . '|' . ( int ) $blBundle . '|' . serialize($sAdditionalParam));
569 
570  return $sItemKey;
571  }
572 
573 
579  public function removeItem($sItemKey)
580  {
581  if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
582  if (isset($this->_aBasketContents[$sItemKey])) {
583  $sArticleId = $this->_aBasketContents[$sItemKey]->getProductId();
584  if ($sArticleId) {
585  $this->getSession()
586  ->getBasketReservations()
587  ->discardArticleReservation($sArticleId);
588  }
589  }
590  }
591  unset($this->_aBasketContents[$sItemKey]);
592 
593  // basket exclude
594  if (!count($this->_aBasketContents) && $this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
595  $this->setBasketRootCatId(null);
596  }
597  }
598 
602  protected function _clearBundles()
603  {
604  reset($this->_aBasketContents);
605  while (list($sItemKey, $oBasketItem) = each($this->_aBasketContents)) {
606  if ($oBasketItem->isBundle()) {
607  $this->removeItem($sItemKey);
608  }
609  }
610  }
611 
619  protected function _getArticleBundles($oBasketItem)
620  {
621  $aBundles = array();
622 
623  if ($oBasketItem->isBundle()) {
624  return $aBundles;
625  }
626 
627  $oArticle = $oBasketItem->getArticle(true);
628  if ($oArticle && $oArticle->oxarticles__oxbundleid->value) {
629  $aBundles[$oArticle->oxarticles__oxbundleid->value] = 1;
630  }
631 
632  return $aBundles;
633  }
634 
635 
644  protected function _getItemBundles($oBasketItem, $aBundles = array())
645  {
646  if ($oBasketItem->isBundle()) {
647  return array();
648  }
649 
650  // does this object still exists ?
651  if ($oArticle = $oBasketItem->getArticle()) {
652  $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketItemBundleDiscounts($oArticle, $this, $this->getBasketUser());
653 
654  foreach ($aDiscounts as $oDiscount) {
655 
656  $iAmnt = $oDiscount->getBundleAmount($oBasketItem->getAmount());
657  if ($iAmnt) {
658  //init array element
659  if (!isset($aBundles[$oDiscount->oxdiscount__oxitmartid->value])) {
660  $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
661  }
662 
663  if ($oDiscount->oxdiscount__oxitmmultiple->value) {
664  $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $iAmnt;
665  } else {
666  $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = $iAmnt;
667  }
668  }
669  }
670  }
671 
672  return $aBundles;
673  }
674 
682  protected function _getBasketBundles($aBundles = array())
683  {
684  $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketBundleDiscounts($this, $this->getBasketUser());
685 
686  // calculating amount of non bundled/discount items
687  $dAmount = 0;
688  foreach ($this->_aBasketContents as $oBasketItem) {
689  if (!($oBasketItem->isBundle() || $oBasketItem->isDiscountArticle())) {
690  $dAmount += $oBasketItem->getAmount();
691  }
692  }
693 
694  foreach ($aDiscounts as $oDiscount) {
695  if ($oDiscount->oxdiscount__oxitmartid->value) {
696  if (!isset($aBundles[$oDiscount->oxdiscount__oxitmartid->value])) {
697  $aBundles[$oDiscount->oxdiscount__oxitmartid->value] = 0;
698  }
699 
700  $aBundles[$oDiscount->oxdiscount__oxitmartid->value] += $oDiscount->getBundleAmount($dAmount);
701  }
702  }
703 
704  return $aBundles;
705  }
706 
711  protected function _addBundles()
712  {
713  $aBundles = array();
714  // iterating through articles and binding bundles
715  foreach ($this->_aBasketContents as $key => $oBasketItem) {
716  try {
717  // adding discount type bundles
718  if (!$oBasketItem->isDiscountArticle() && !$oBasketItem->isBundle()) {
719  $aBundles = $this->_getItemBundles($oBasketItem, $aBundles);
720  } else {
721  continue;
722  }
723 
724  // adding item type bundles
725  $aArtBundles = $this->_getArticleBundles($oBasketItem);
726 
727  // adding bundles to basket
728  $this->_addBundlesToBasket($aArtBundles);
729  } catch (oxNoArticleException $oEx) {
730  $this->removeItem($key);
731  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
732  } catch (oxArticleInputException $oEx) {
733  $this->removeItem($key);
734  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
735  }
736  }
737 
738  // adding global basket bundles
739  $aBundles = $this->_getBasketBundles($aBundles);
740 
741  // adding all bundles to basket
742  if ($aBundles) {
743  $this->_addBundlesToBasket($aBundles);
744  }
745  }
746 
752  protected function _addBundlesToBasket($aBundles)
753  {
754  foreach ($aBundles as $sBundleId => $dAmount) {
755  if ($dAmount) {
756  try {
757  if ($oBundleItem = $this->addToBasket($sBundleId, $dAmount, null, null, false, true)) {
758  $oBundleItem->setAsDiscountArticle(true);
759  }
760  } catch (oxArticleException $oEx) {
761  // caught and ignored
762  if ($oEx instanceof oxOutOfStockException && $oEx->getRemainingAmount() > 0) {
763  $sItemId = $this->getItemKey($sBundleId, null, null, true);
764  $this->_aBasketContents[$sItemId]->setAsDiscountArticle( true );
765  }
766  }
767  }
768  }
769 
770  }
771 
775  protected function _calcItemsPrice()
776  {
777  // resetting
778  $this->setSkipDiscounts(false);
779  $this->_iProductsCnt = 0; // count different types
780  $this->_dItemsCnt = 0; // count of item units
781  $this->_dWeight = 0; // basket weight
782 
783  $this->_oProductsPriceList = oxNew('oxpricelist');
784  $this->_oDiscountProductsPriceList = oxNew('oxpricelist');
785  $this->_oNotDiscountedProductsPriceList = oxNew('oxpricelist');
786 
787  $oDiscountList = oxRegistry::get("oxDiscountList");
788 
789  foreach ($this->_aBasketContents as $oBasketItem) {
790  $this->_iProductsCnt++;
791  $this->_dItemsCnt += $oBasketItem->getAmount();
792  $this->_dWeight += $oBasketItem->getWeight();
793 
794  if (!$oBasketItem->isDiscountArticle() && ($oArticle = $oBasketItem->getArticle(true))) {
795 
796  $oBasketPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this);
797  $oBasketItem->setRegularUnitPrice(clone $oBasketPrice);
798 
799  if (!$oArticle->skipDiscounts() && $this->canCalcDiscounts()) {
800  // apply basket type discounts for item
801  $aDiscounts = $oDiscountList->getBasketItemDiscounts($oArticle, $this, $this->getBasketUser());
802  reset($aDiscounts);
803  foreach ($aDiscounts as $oDiscount) {
804  $oBasketPrice->setDiscount($oDiscount->getAddSum(), $oDiscount->getAddSumType());
805  }
806  $oBasketPrice->calculateDiscount();
807  } else {
808  $oBasketItem->setSkipDiscounts(true);
809  $this->setSkipDiscounts(true);
810  }
811 
812  $oBasketItem->setPrice($oBasketPrice);
813  $this->_oProductsPriceList->addToPriceList($oBasketItem->getPrice());
814 
815  //P collect discount values for basket items which are discountable
816  if (!$oArticle->skipDiscounts()) {
817 
818  $this->_oDiscountProductsPriceList->addToPriceList($oBasketItem->getPrice());
819  } else {
820  $this->_oNotDiscountedProductsPriceList->addToPriceList($oBasketItem->getPrice());
821  $oBasketItem->setSkipDiscounts(true);
822  $this->setSkipDiscounts(true);
823  }
824  } elseif ($oBasketItem->isBundle()) {
825  // if bundles price is set to zero
826  $oPrice = oxNew("oxprice");
827  $oBasketItem->setPrice($oPrice);
828  }
829  }
830  }
831 
837  public function setDiscountCalcMode($blCalcDiscounts)
838  {
839  $this->_blCalcDiscounts = $blCalcDiscounts;
840  }
841 
847  public function canCalcDiscounts()
848  {
850  }
851 
861  protected function _mergeDiscounts($aDiscounts, $aItemDiscounts)
862  {
863  foreach ($aItemDiscounts as $sKey => $oDiscount) {
864  // add prices of the same discounts
865  if (array_key_exists($sKey, $aDiscounts)) {
866  $aDiscounts[$sKey]->dDiscount += $oDiscount->dDiscount;
867  } else {
868  $aDiscounts[$sKey] = $oDiscount;
869  }
870  }
871 
872  return $aDiscounts;
873  }
874 
880  protected function _calcDeliveryCost()
881  {
882  if ($this->_oDeliveryPrice !== null) {
883  return $this->_oDeliveryPrice;
884  }
885  $myConfig = $this->getConfig();
886  $oDeliveryPrice = oxNew('oxprice');
887 
888  if ($this->getConfig()->getConfigParam('blDeliveryVatOnTop')) {
889  $oDeliveryPrice->setNettoPriceMode();
890  } else {
891  $oDeliveryPrice->setBruttoPriceMode();
892  }
893 
894  // don't calculate if not logged in
895  $oUser = $this->getBasketUser();
896 
897  if (!$oUser && !$myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn')) {
898  return $oDeliveryPrice;
899  }
900 
901  $fDelVATPercent = $this->getAdditionalServicesVatPercent();
902  $oDeliveryPrice->setVat($fDelVATPercent);
903 
904  // list of active delivery costs
905  if ($myConfig->getConfigParam('bl_perfLoadDelivery')) {
906  $aDeliveryList = oxRegistry::get("oxDeliveryList")->getDeliveryList(
907  $this,
908  $oUser,
909  $this->_findDelivCountry(),
910  $this->getShippingId()
911  );
912 
913  if (count($aDeliveryList) > 0) {
914  foreach ($aDeliveryList as $oDelivery) {
915  //debug trace
916  if ($myConfig->getConfigParam('iDebug') == 5) {
917  echo("DelCost : " . $oDelivery->oxdelivery__oxtitle->value . "<br>");
918  }
919  $oDeliveryPrice->addPrice($oDelivery->getDeliveryPrice($fDelVATPercent));
920  }
921  }
922  }
923 
924  return $oDeliveryPrice;
925  }
926 
932  public function getBasketUser()
933  {
934  if ($this->_oUser == null) {
935  return $this->getUser();
936  }
937 
938  return $this->_oUser;
939  }
940 
946  public function setBasketUser($oUser)
947  {
948  $this->_oUser = $oUser;
949  }
950 
951  //P
957  public function getMostUsedVatPercent()
958  {
959  if ($this->_oProductsPriceList) {
960  return $this->_oProductsPriceList->getMostUsedVatPercent();
961  }
962  }
963 
970  {
971  if ($this->_oProductsPriceList) {
972  if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
973  return $this->_oProductsPriceList->getProportionalVatPercent();
974  } else {
975  return $this->_oProductsPriceList->getMostUsedVatPercent();
976  }
977  }
978  }
979 
985  public function isProportionalCalculationOn()
986  {
987  if ($this->getConfig()->getConfigParam('sAdditionalServVATCalcMethod') == 'proportional') {
988  return true;
989  }
990 
991  return false;
992  }
993 
994 
995  //P
999  protected function _calcTotalPrice()
1000  {
1001  // 1. add products price
1002  $dPrice = $this->_dBruttoSum;
1003 
1004  $oTotalPrice = oxNew('oxPrice');
1005  $oTotalPrice->setBruttoPriceMode();
1006  $oTotalPrice->setPrice($dPrice);
1007 
1008  // 2. subtract discounts
1009  if ($dPrice && !$this->isCalculationModeNetto()) {
1010 
1011  // 2.2 applying basket discounts
1012  $oTotalPrice->subtract($this->_oTotalDiscount->getBruttoPrice());
1013 
1014  // 2.3 applying voucher discounts
1015  if ($oVoucherDisc = $this->getVoucherDiscount()) {
1016  $oTotalPrice->subtract($oVoucherDisc->getBruttoPrice());
1017  }
1018  }
1019 
1020  // 2.3 add delivery cost
1021  if (isset($this->_aCosts['oxdelivery'])) {
1022  $oTotalPrice->add($this->_aCosts['oxdelivery']->getBruttoPrice());
1023  }
1024 
1025  // 2.4 add wrapping price
1026  if (isset($this->_aCosts['oxwrapping'])) {
1027  $oTotalPrice->add($this->_aCosts['oxwrapping']->getBruttoPrice());
1028  }
1029  if (isset($this->_aCosts['oxgiftcard'])) {
1030  $oTotalPrice->add($this->_aCosts['oxgiftcard']->getBruttoPrice());
1031  }
1032 
1033  // 2.5 add payment price
1034  if (isset($this->_aCosts['oxpayment'])) {
1035  $oTotalPrice->add($this->_aCosts['oxpayment']->getBruttoPrice());
1036  }
1037 
1038  // 2.6 add TS protection price
1039  if (isset($this->_aCosts['oxtsprotection'])) {
1040  $oTotalPrice->add($this->_aCosts['oxtsprotection']->getBruttoPrice());
1041  }
1042 
1043  $this->setPrice($oTotalPrice);
1044  }
1045 
1051  public function setVoucherDiscount($dDiscount)
1052  {
1053  $this->_oVoucherDiscount = oxNew('oxPrice');
1054  $this->_oVoucherDiscount->setBruttoPriceMode();
1055  $this->_oVoucherDiscount->add($dDiscount);
1056  }
1057 
1061  protected function _calcVoucherDiscount()
1062  {
1063  if ($this->getConfig()->getConfigParam('bl_showVouchers') && ($this->_oVoucherDiscount === null || ($this->_blUpdateNeeded && !$this->isAdmin()))) {
1064 
1065  $this->_oVoucherDiscount = $this->_getPriceObject();
1066 
1067  // calculating price to apply discount
1068  $dPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto()) - $this->_oTotalDiscount->getPrice();
1069 
1070  // recalculating
1071  if (count($this->_aVouchers)) {
1072  $oLang = oxRegistry::getLang();
1073  foreach ($this->_aVouchers as $sVoucherId => $oStdVoucher) {
1074  $oVoucher = oxNew('oxvoucher');
1075  try { // checking
1076  $oVoucher->load($oStdVoucher->sVoucherId);
1077 
1078  if (!$this->_blSkipVouchersAvailabilityChecking) {
1079  $oVoucher->checkBasketVoucherAvailability($this->_aVouchers, $dPrice);
1080  $oVoucher->checkUserAvailability($this->getBasketUser());
1081  }
1082 
1083  // assigning real voucher discount value as this is the only place where real value is calculated
1084  $dVoucherdiscount = $oVoucher->getDiscountValue($dPrice);
1085 
1086  if ($dVoucherdiscount > 0) {
1087 
1088  if ($oVoucher->getDiscountType() == 'absolute') {
1089  $dVatPart = ($dPrice - $dVoucherdiscount) / $dPrice * 100;
1090  } else {
1091  $dVatPart = 100 - $oVoucher->getDiscount();
1092  }
1093 
1094  if (!$this->_aDiscountedVats) {
1095  if ($oPriceList = $this->getDiscountProductsPrice()) {
1096  $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
1097  }
1098  }
1099 
1100  // apply discount to vat
1101  foreach ($this->_aDiscountedVats as $sKey => $dVat) {
1102  $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
1103  }
1104  }
1105 
1106  // accumulating discount value
1107  $this->_oVoucherDiscount->add($dVoucherdiscount);
1108 
1109  // collecting formatted for preview
1110  $oStdVoucher->fVoucherdiscount = $oLang->formatCurrency($dVoucherdiscount, $this->getBasketCurrency());
1111  $oStdVoucher->dVoucherdiscount = $dVoucherdiscount;
1112 
1113  // subtracting voucher discount
1114  $dPrice = $dPrice - $dVoucherdiscount;
1115 
1116 
1117  } catch (oxVoucherException $oEx) {
1118 
1119  // removing voucher on error
1120  $oVoucher->unMarkAsReserved();
1121  unset($this->_aVouchers[$sVoucherId]);
1122 
1123  // storing voucher error info
1124  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
1125  }
1126  }
1127  }
1128  }
1129  }
1130 
1134  protected function _applyDiscounts()
1135  {
1136  //apply discounts for brutto price
1137  $dDiscountedSum = $this->_getDiscountedProductsSum();
1138 
1139  $oUtils = oxRegistry::getUtils();
1140  $dVatSum = 0;
1141  foreach ($this->_aDiscountedVats as $dVat) {
1142  $dVatSum += $oUtils->fRound($dVat, $this->_oCurrency);
1143  }
1144 
1145  $oNotDiscounted = $this->getNotDiscountProductsPrice();
1146 
1147  if ($this->isCalculationModeNetto()) {
1148  // netto view mode
1149  $this->setNettoSum($this->getProductsPrice()->getSum());
1150  $this->setBruttoSum($oNotDiscounted->getSum(false) + $dDiscountedSum + $dVatSum);
1151  } else {
1152  // brutto view mode
1153  $this->setNettoSum($oNotDiscounted->getSum() + $dDiscountedSum - $dVatSum);
1154  $this->setBruttoSum($this->getProductsPrice()->getSum(false));
1155  }
1156  }
1157 
1163  public function isPriceViewModeNetto()
1164  {
1165  $blResult = (bool) $this->getConfig()->getConfigParam('blShowNetPrice');
1166  $oUser = $this->getBasketUser();
1167  if ($oUser) {
1168  $blResult = $oUser->isPriceViewModeNetto();
1169  }
1170 
1171  return $blResult;
1172  }
1173 
1179  protected function _getPriceObject()
1180  {
1181  $oPrice = oxNew('oxPrice');
1182 
1183  if ($this->isCalculationModeNetto()) {
1184  $oPrice->setNettoPriceMode();
1185  } else {
1186  $oPrice->setBruttoPriceMode();
1187  }
1188 
1189  return $oPrice;
1190  }
1191 
1195  protected function _calcBasketDiscount()
1196  {
1197  // resetting
1198  $this->_aDiscounts = array();
1199 
1200  // P using prices sum which has discount, not sum of skipped discounts
1201  $dOldPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto());
1202 
1203  // add basket discounts
1204  if ($this->_oTotalDiscount !== null && isset($this->_isForOrderRecalculation) && $this->_isForOrderRecalculation) {
1205  //if total discount was set on order recalculation
1206  $oTotalPrice = $this->getTotalDiscount();
1207  $oDiscount = oxNew('oxDiscount');
1208  $oDiscount->oxdiscount__oxaddsum = new oxField($oTotalPrice->getPrice());
1209  $oDiscount->oxdiscount__oxaddsumtype = new oxField('abs');
1210  $aDiscounts[] = $oDiscount;
1211  } else {
1212  // discounts for basket
1213  $aDiscounts = oxRegistry::get("oxDiscountList")->getBasketDiscounts($this, $this->getBasketUser());
1214  }
1215 
1216  if ($oPriceList = $this->getDiscountProductsPrice()) {
1217  $this->_aDiscountedVats = $oPriceList->getVatInfo($this->isCalculationModeNetto());
1218  }
1219 
1220  foreach ($aDiscounts as $oDiscount) {
1221 
1222  // storing applied discounts
1223  $oStdDiscount = $oDiscount->getSimpleDiscount();
1224 
1225  // skipping bundle discounts
1226  if ($oDiscount->oxdiscount__oxaddsumtype->value == 'itm') {
1227  continue;
1228  }
1229 
1230  // saving discount info
1231  $oStdDiscount->dDiscount = $oDiscount->getAbsValue($dOldPrice);
1232 
1233  $dVatPart = 100 - $oDiscount->getPercentage($dOldPrice);
1234 
1235  // if discount is more than basket sum
1236  if ($dOldPrice < $oStdDiscount->dDiscount) {
1237  $oStdDiscount->dDiscount = $dOldPrice;
1238  $dVatPart = 0;
1239  }
1240 
1241  // apply discount to vat
1242  foreach ($this->_aDiscountedVats as $sKey => $dVat) {
1243  $this->_aDiscountedVats[$sKey] = oxPrice::percent($dVat, $dVatPart);
1244  }
1245 
1246  //storing discount
1247  if ($oStdDiscount->dDiscount != 0) {
1248  $this->_aDiscounts[$oDiscount->getId()] = $oStdDiscount;
1249  // subtracting product price after discount
1250  $dOldPrice = $dOldPrice - $oStdDiscount->dDiscount;
1251  }
1252  }
1253  }
1254 
1258  protected function _calcBasketTotalDiscount()
1259  {
1260  if ($this->_oTotalDiscount === null || (!$this->isAdmin())) {
1261 
1262  $this->_oTotalDiscount = $this->_getPriceObject();
1263 
1264  if (is_array($this->_aDiscounts)) {
1265  foreach ($this->_aDiscounts as $oDiscount) {
1266 
1267  // skipping bundle discounts
1268  if ($oDiscount->sType == 'itm') {
1269  continue;
1270  }
1271 
1272  // add discount value to total basket discount
1273  $this->_oTotalDiscount->add($oDiscount->dDiscount);
1274  }
1275  }
1276  }
1277  }
1278 
1287  protected function _calcBasketWrapping()
1288  {
1289  $oWrappingPrices = oxNew('oxPriceList');
1290 
1291  foreach ($this->_aBasketContents as $oBasketItem) {
1292 
1293  if (($oWrapping = $oBasketItem->getWrapping())) {
1294 
1295  $oWrappingPrice = $oWrapping->getWrappingPrice($oBasketItem->getAmount());
1296  $oWrappingPrice->setVat($oBasketItem->getPrice()->getVat());
1297 
1298  $oWrappingPrices->addToPriceList($oWrappingPrice);
1299  }
1300  }
1301 
1302  if ($oWrappingPrices->getCount()) {
1303  $oWrappingCost = oxNew('oxPrice');
1304  $oWrappingCost = $oWrappingPrices->calculateToPrice();
1305  }
1306 
1307  return $oWrappingCost;
1308  }
1309 
1318  protected function _calcBasketGiftCard()
1319  {
1320  $oGiftCardPrice = oxNew('oxPrice');
1321 
1322  if ($this->getConfig()->getConfigParam('blWrappingVatOnTop')) {
1323  $oGiftCardPrice->setNettoPriceMode();
1324  } else {
1325  $oGiftCardPrice->setBruttoPriceMode();
1326  }
1327 
1328  $dVATPercent = $this->getAdditionalServicesVatPercent();
1329 
1330  $oGiftCardPrice->setVat($dVATPercent);
1331 
1332  // gift card price calculation
1333  if (($oCard = $this->getCard())) {
1334  if ($dVATPercent !== null) {
1335  $oCard->setWrappingVat($dVATPercent);
1336  }
1337  $oGiftCardPrice->addPrice($oCard->getWrappingPrice());
1338  }
1339 
1340  return $oGiftCardPrice;
1341  }
1342 
1349  protected function _calcPaymentCost()
1350  {
1351  // resetting values
1352  $oPaymentPrice = oxNew('oxPrice');
1353 
1354  // payment
1355  if (($this->_sPaymentId = $this->getPaymentId())) {
1356 
1357  $oPayment = oxNew('oxPayment');
1358  $oPayment->load($this->_sPaymentId);
1359 
1360  $oPayment->calculate($this);
1361  $oPaymentPrice = $oPayment->getPrice();
1362  }
1363 
1364  return $oPaymentPrice;
1365  }
1366 
1373  protected function _calcTsProtectionCost()
1374  {
1375  if (($this->getTsProductId())) {
1376  $oTsProtection = oxNew('oxtsprotection');
1377  $oTsProduct = $oTsProtection->getTsProduct($this->getTsProductId());
1378  $oProtectionPrice = $oTsProduct->getPrice();
1379  $oProtectionPrice->setVat($this->getAdditionalServicesVatPercent());
1380  } else {
1381  $oProtectionPrice = oxNew('oxPrice');
1382  }
1383 
1384  return $oProtectionPrice;
1385  }
1386 
1393  public function setCost($sCostName, $oPrice = null)
1394  {
1395  $this->_aCosts[$sCostName] = $oPrice;
1396  }
1397 
1406  public function calculateBasket($blForceUpdate = false)
1407  {
1408  /*
1409  //would be good to perform the reset of previous calculation
1410  //at least you can use it for the debug
1411  $this->_aDiscounts = array();
1412  $this->_aItemDiscounts = array();
1413  $this->_oTotalDiscount = null;
1414  $this->_dDiscountedProductNettoPrice = 0;
1415  $this->_aDiscountedVats = array();
1416  $this->_oPrice = null;
1417  $this->_oNotDiscountedProductsPriceList = null;
1418  $this->_oProductsPriceList = null;
1419  $this->_oDiscountProductsPriceList = null;*/
1420 
1421  if (!$this->isEnabled()) {
1422  return;
1423  }
1424 
1425  if ($blForceUpdate) {
1426  $this->onUpdate();
1427  }
1428 
1429  if (!($this->_blUpdateNeeded || $blForceUpdate)) {
1430  return;
1431  }
1432 
1433  $this->_aCosts = array();
1434 
1435  // 1. saving basket to the database
1436  $this->_save();
1437 
1438  // 2. remove all bundles
1439  $this->_clearBundles();
1440 
1441  // 3. generate bundle items
1442  $this->_addBundles();
1443 
1444  // reserve active basket
1445  if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
1446  $this->getSession()->getBasketReservations()->reserveBasket($this);
1447  }
1448 
1449  // 4. calculating item prices
1450  $this->_calcItemsPrice();
1451 
1452  // 5. calculating/applying discounts
1453  $this->_calcBasketDiscount();
1454 
1455  // 6. calculating basket total discount
1456  $this->_calcBasketTotalDiscount();
1457 
1458  // 7. check for vouchers
1459  $this->_calcVoucherDiscount();
1460 
1461  // 8. applies all discounts to pricelist
1462  $this->_applyDiscounts();
1463 
1464  // 9. calculating additional costs:
1465  // 9.1: delivery
1466  $this->setCost('oxdelivery', $this->_calcDeliveryCost());
1467 
1468  // 9.2: adding wrapping and gift card costs
1469  $this->setCost('oxwrapping', $this->_calcBasketWrapping());
1470 
1471  $this->setCost('oxgiftcard', $this->_calcBasketGiftCard());
1472 
1473  // 9.3: adding payment cost
1474  $this->setCost('oxpayment', $this->_calcPaymentCost());
1475 
1476  // 9.4: adding TS protection cost
1477  $this->setCost('oxtsprotection', $this->_calcTsProtectionCost());
1478 
1479  // 10. calculate total price
1480  $this->_calcTotalPrice();
1481 
1482  // 11. formatting discounts
1483  $this->formatDiscount();
1484 
1485  // 12.setting to up-to-date status
1486  $this->afterUpdate();
1487  }
1488 
1492  public function onUpdate()
1493  {
1494  $this->_blUpdateNeeded = true;
1495  }
1496 
1500  public function afterUpdate()
1501  {
1502  $this->_blUpdateNeeded = false;
1503  }
1504 
1512  public function getBasketSummary()
1513  {
1514  if ($this->_blUpdateNeeded || $this->_aBasketSummary === null) {
1515  $this->_aBasketSummary = new stdclass();
1516  $this->_aBasketSummary->aArticles = array();
1517  $this->_aBasketSummary->aCategories = array();
1518  $this->_aBasketSummary->iArticleCount = 0;
1519  $this->_aBasketSummary->dArticlePrice = 0;
1520  $this->_aBasketSummary->dArticleDiscountablePrice = 0;
1521  }
1522 
1523  if (!$this->isEnabled()) {
1524  return $this->_aBasketSummary;
1525  }
1526 
1527  $myConfig = $this->getConfig();
1528  foreach ($this->_aBasketContents as $oBasketItem) {
1529  if (!$oBasketItem->isBundle() && $oArticle = $oBasketItem->getArticle(false)) {
1530  $aCatIds = $oArticle->getCategoryIds();
1531  //#M530 if price is not loaded for articles
1532  $dPrice = 0;
1533  $dDiscountablePrice = 0;
1534  if (($oPrice = $oArticle->getBasketPrice($oBasketItem->getAmount(), $oBasketItem->getSelList(), $this))) {
1535  $dPrice = $oPrice->getPrice();
1536  if (!$oArticle->skipDiscounts()) {
1537  $dDiscountablePrice = $dPrice;
1538  }
1539  }
1540 
1541  foreach ($aCatIds as $sCatId) {
1542  if (!isset($this->_aBasketSummary->aCategories[$sCatId])) {
1543  $this->_aBasketSummary->aCategories[$sCatId] = new stdClass();
1544  }
1545 
1546  $this->_aBasketSummary->aCategories[$sCatId]->dPrice += $dPrice * $oBasketItem->getAmount();
1547  $this->_aBasketSummary->aCategories[$sCatId]->dDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
1548  $this->_aBasketSummary->aCategories[$sCatId]->dAmount += $oBasketItem->getAmount();
1549  $this->_aBasketSummary->aCategories[$sCatId]->iCount++;
1550  }
1551 
1552  // variant handling
1553  if (($sParentId = $oArticle->getParentId()) && $myConfig->getConfigParam('blVariantParentBuyable')) {
1554  if (!isset($this->_aBasketSummary->aArticles[$sParentId])) {
1555  $this->_aBasketSummary->aArticles[$sParentId] = 0;
1556  }
1557  $this->_aBasketSummary->aArticles[$sParentId] += $oBasketItem->getAmount();
1558  }
1559 
1560  if (!isset($this->_aBasketSummary->aArticles[$oBasketItem->getProductId()])) {
1561  $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] = 0;
1562  }
1563 
1564  $this->_aBasketSummary->aArticles[$oBasketItem->getProductId()] += $oBasketItem->getAmount();
1565  $this->_aBasketSummary->iArticleCount += $oBasketItem->getAmount();
1566  $this->_aBasketSummary->dArticlePrice += $dPrice * $oBasketItem->getAmount();
1567  $this->_aBasketSummary->dArticleDiscountablePrice += $dDiscountablePrice * $oBasketItem->getAmount();
1568  }
1569  }
1570 
1571  return $this->_aBasketSummary;
1572  }
1573 
1583  public function addVoucher($sVoucherId)
1584  {
1585  // calculating price to check
1586  // P using prices sum which has discount, not sum of skipped discounts
1587  $dPrice = 0;
1588  if ($this->_oDiscountProductsPriceList) {
1589  $dPrice = $this->_oDiscountProductsPriceList->getSum($this->isCalculationModeNetto());
1590  }
1591 
1592  try { // trying to load voucher and apply it
1593 
1594  $oVoucher = oxNew('oxvoucher');
1595 
1596  if (!$this->_blSkipVouchersAvailabilityChecking) {
1597  $oVoucher->getVoucherByNr($sVoucherId, $this->_aVouchers, true);
1598  $oVoucher->checkVoucherAvailability($this->_aVouchers, $dPrice);
1599  $oVoucher->checkUserAvailability($this->getBasketUser());
1600  $oVoucher->markAsReserved();
1601  } else {
1602  $oVoucher->load($sVoucherId);
1603  }
1604 
1605  // saving voucher info
1606  $this->_aVouchers[$oVoucher->oxvouchers__oxid->value] = $oVoucher->getSimpleVoucher();
1607  } catch (oxVoucherException $oEx) {
1608 
1609  // problems adding voucher
1610  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx, false, true);
1611  }
1612 
1613  $this->onUpdate();
1614  }
1615 
1621  public function removeVoucher($sVoucherId)
1622  {
1623  // removing if it exists
1624  if (isset($this->_aVouchers[$sVoucherId])) {
1625 
1626  $oVoucher = oxNew('oxVoucher');
1627  $oVoucher->load($sVoucherId);
1628 
1629  $oVoucher->unMarkAsReserved();
1630 
1631  // unset it if exists this voucher in DB or not
1632  unset($this->_aVouchers[$sVoucherId]);
1633  $this->onUpdate();
1634  }
1635 
1636  }
1637 
1641  public function resetUserInfo()
1642  {
1643  $this->setPayment(null);
1644  $this->setShipping(null);
1645  }
1646 
1650  protected function formatDiscount()
1651  {
1652  // discount information
1653  // formatting discount value
1654  $this->aDiscounts = $this->getDiscounts();
1655  if (count($this->aDiscounts) > 0) {
1656  $oLang = oxRegistry::getLang();
1657  foreach ($this->aDiscounts as $oDiscount) {
1658  $oDiscount->fDiscount = $oLang->formatCurrency($oDiscount->dDiscount, $this->getBasketCurrency());
1659  }
1660  }
1661  }
1662 
1670  protected function _canSaveBasket()
1671  {
1672  return $this->isSaveToDataBaseEnabled();
1673  }
1674 
1680  public function load()
1681  {
1682  $oUser = $this->getBasketUser();
1683  if (!$oUser) {
1684  return;
1685  }
1686 
1687  $oBasket = $oUser->getBasket('savedbasket');
1688 
1689  // restoring from saved history
1690  $aSavedItems = $oBasket->getItems();
1691  foreach ($aSavedItems as $oItem) {
1692  try {
1693  $oSelList = $oItem->getSelList();
1694 
1695  $this->addToBasket($oItem->oxuserbasketitems__oxartid->value, $oItem->oxuserbasketitems__oxamount->value, $oSelList, $oItem->getPersParams(), true);
1696  } catch (oxArticleException $oEx) {
1697  // caught and ignored
1698  }
1699  }
1700  }
1701 
1705  protected function _save()
1706  {
1707  if ($this->isSaveToDataBaseEnabled()) {
1708 
1709  if ($oUser = $this->getBasketUser()) {
1710  //first delete all contents
1711  //#2039
1712  $oSavedBasket = $oUser->getBasket('savedbasket');
1713  $oSavedBasket->delete();
1714 
1715  //then save
1716  foreach ($this->_aBasketContents as $oBasketItem) {
1717  // discount or bundled products will be added automatically if available
1718  if (!$oBasketItem->isBundle() && !$oBasketItem->isDiscountArticle()) {
1719  $oSavedBasket->addItemToBasket($oBasketItem->getProductId(), $oBasketItem->getAmount(), $oBasketItem->getSelList(), true, $oBasketItem->getPersParams());
1720  }
1721  }
1722  }
1723  }
1724  }
1725 
1731  protected function _deleteSavedBasket()
1732  {
1733  // deleting basket if session user available
1734  if ($oUser = $this->getBasketUser()) {
1735  $oUser->getBasket('savedbasket')->delete();
1736  }
1737 
1738  // basket exclude
1739  if ($this->getConfig()->getConfigParam('blBasketExcludeEnabled')) {
1740  $this->setBasketRootCatId(null);
1741  }
1742  }
1743 
1749  protected function _findDelivCountry()
1750  {
1751  $myConfig = $this->getConfig();
1752  $oUser = $this->getBasketUser();
1753 
1754  $sDeliveryCountry = null;
1755 
1756  if (!$oUser) {
1757  // don't calculate if not logged in unless specified otherwise
1758  $aHomeCountry = $myConfig->getConfigParam('aHomeCountry');
1759  if ($myConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn') && is_array($aHomeCountry)) {
1760  $sDeliveryCountry = current($aHomeCountry);
1761  }
1762  } else {
1763 
1764  // ok, logged in
1765  if ($sCountryId = $myConfig->getGlobalParameter('delcountryid')) {
1766  $sDeliveryCountry = $sCountryId;
1767  } elseif ($sAddressId = oxRegistry::getSession()->getVariable('deladrid')) {
1768 
1769  $oDeliveryAddress = oxNew('oxAddress');
1770  if ($oDeliveryAddress->load($sAddressId)) {
1771  $sDeliveryCountry = $oDeliveryAddress->oxaddress__oxcountryid->value;
1772  }
1773  }
1774 
1775  // still not found ?
1776  if (!$sDeliveryCountry) {
1777  $sDeliveryCountry = $oUser->oxuser__oxcountryid->value;
1778  }
1779  }
1780 
1781  return $sDeliveryCountry;
1782  }
1783 
1787  public function deleteBasket()
1788  {
1789  $this->_aBasketContents = array();
1790  $this->getSession()->delBasket();
1791 
1792  if ($this->getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
1793  $this->getSession()->getBasketReservations()->discardReservations();
1794  }
1795 
1796  // merging basket history
1797  $this->_deleteSavedBasket();
1798  }
1799 
1805  public function setPayment($sPaymentId = null)
1806  {
1807  $this->_sPaymentId = $sPaymentId;
1808  }
1809 
1815  public function getPaymentId()
1816  {
1817  if (!$this->_sPaymentId) {
1818  $this->_sPaymentId = oxRegistry::getSession()->getVariable('paymentid');
1819  }
1820 
1821  return $this->_sPaymentId;
1822  }
1823 
1829  public function setShipping($sShippingSetId = null)
1830  {
1831  $this->_sShippingSetId = $sShippingSetId;
1832  oxRegistry::getSession()->setVariable('sShipSet', $sShippingSetId);
1833  }
1834 
1840  public function setDeliveryPrice($oShippingPrice = null)
1841  {
1842  $this->_oDeliveryPrice = $oShippingPrice;
1843  }
1844 
1850  public function getShippingId()
1851  {
1852  if (!$this->_sShippingSetId) {
1853  $this->_sShippingSetId = oxRegistry::getSession()->getVariable('sShipSet');
1854  }
1855 
1856  $sActPaymentId = $this->getPaymentId();
1857  // setting default if none is set
1858  if (!$this->_sShippingSetId && $sActPaymentId != 'oxempty') {
1859  $oUser = $this->getUser();
1860 
1861  // choosing first preferred delivery set
1862  list(, $sActShipSet) = oxRegistry::get("oxDeliverySetList")->getDeliverySetData(null, $oUser, $this);
1863  // in case nothing was found and no user set - choosing default
1864  $this->_sShippingSetId = $sActShipSet ? $sActShipSet : ($oUser ? null : 'oxidstandard');
1865  } elseif (!$this->isAdmin() && $sActPaymentId == 'oxempty') {
1866  // in case 'oxempty' is payment id - delivery set must be reset
1867  $this->_sShippingSetId = null;
1868  }
1869 
1870  return $this->_sShippingSetId;
1871  }
1872 
1878  public function getBasketArticles()
1879  {
1880  $aBasketArticles = array();
1881 
1882  foreach ($this->_aBasketContents as $sItemKey => $oBasketItem) {
1883  try {
1884  $oProduct = $oBasketItem->getArticle(true);
1885 
1886  if ($this->getConfig()->getConfigParam('bl_perfLoadSelectLists')) {
1887  // marking chosen select list
1888  $aSelList = $oBasketItem->getSelList();
1889  if (is_array($aSelList) && ($aSelectlist = $oProduct->getSelectLists($sItemKey))) {
1890  reset($aSelList);
1891  while (list($conkey, $iSel) = each($aSelList)) {
1892  $aSelectlist[$conkey][$iSel] = $aSelectlist[$conkey][$iSel];
1893  $aSelectlist[$conkey][$iSel]->selected = 1;
1894  }
1895  $oProduct->setSelectlist($aSelectlist);
1896  }
1897  }
1898  } catch (oxNoArticleException $oEx) {
1899  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
1900  $this->removeItem($sItemKey);
1901  $this->calculateBasket(true);
1902  continue;
1903  } catch (oxArticleInputException $oEx) {
1904  oxRegistry::get("oxUtilsView")->addErrorToDisplay($oEx);
1905  $this->removeItem($sItemKey);
1906  $this->calculateBasket(true);
1907  continue;
1908  }
1909 
1910  $aBasketArticles[$sItemKey] = $oProduct;
1911  }
1912 
1913  return $aBasketArticles;
1914  }
1915 
1921  public function getDiscountProductsPrice()
1922  {
1924  }
1925 
1931  public function getProductsPrice()
1932  {
1933  if (is_null($this->_oProductsPriceList)) {
1934  $this->_oProductsPriceList = oxNew('oxPriceList');
1935  }
1936 
1938  }
1939 
1945  public function getPrice()
1946  {
1947  if (is_null($this->_oPrice)) {
1948  $this->setPrice(oxNew('oxPrice'));
1949  }
1950 
1951  return $this->_oPrice;
1952  }
1953 
1959  public function setPrice($oPrice)
1960  {
1961  $this->_oPrice = $oPrice;
1962  }
1963 
1964 
1971  public function getOrderId()
1972  {
1973  return $this->_sOrderId;
1974  }
1975 
1981  public function setOrderId($sId)
1982  {
1983  $this->_sOrderId = $sId;
1984  }
1985 
1994  public function getCosts($sId = null)
1995  {
1996  // if user want some specific cost - return it
1997  if ($sId) {
1998  return isset($this->_aCosts[$sId]) ? $this->_aCosts[$sId] : null;
1999  }
2000 
2001  return $this->_aCosts;
2002  }
2003 
2009  public function getVouchers()
2010  {
2011  return $this->_aVouchers;
2012  }
2013 
2019  public function getProductsCount()
2020  {
2021  return $this->_iProductsCnt;
2022  }
2023 
2029  public function getItemsCount()
2030  {
2031  return $this->_dItemsCnt;
2032  }
2033 
2039  public function getWeight()
2040  {
2041  return $this->_dWeight;
2042  }
2043 
2049  public function getContents()
2050  {
2051  return $this->_aBasketContents;
2052  }
2053 
2061  public function getProductVats($blFormatCurrency = true)
2062  {
2063  if (!$this->_oNotDiscountedProductsPriceList) {
2064  return array();
2065  }
2066 
2067  $aVats = $this->_oNotDiscountedProductsPriceList->getVatInfo($this->isCalculationModeNetto());
2068 
2069  $oUtils = oxRegistry::getUtils();
2070  foreach ($this->_aDiscountedVats as $sKey => $dVat) {
2071  if (!isset($aVats[$sKey])) {
2072  $aVats[$sKey] = 0;
2073  }
2074  // add prices of the same discounts
2075  $aVats[$sKey] += $oUtils->fRound($dVat, $this->_oCurrency);
2076  }
2077 
2078  if ($blFormatCurrency) {
2079  $oLang = oxRegistry::getLang();
2080  foreach ($aVats as $sKey => $dVat) {
2081  $aVats[$sKey] = $oLang->formatCurrency($dVat, $this->getBasketCurrency());
2082  }
2083  }
2084 
2085  return $aVats;
2086  }
2087 
2093  public function setCardMessage($sMessage)
2094  {
2095  $this->_sCardMessage = $sMessage;
2096  }
2097 
2103  public function getCardMessage()
2104  {
2105  return $this->_sCardMessage;
2106  }
2107 
2113  public function setCardId($sCardId)
2114  {
2115  $this->_sCardId = $sCardId;
2116  }
2117 
2123  public function getCardId()
2124  {
2125  return $this->_sCardId;
2126  }
2127 
2133  public function getCard()
2134  {
2135  $oCard = null;
2136  if ($sCardId = $this->getCardId()) {
2137  $oCard = oxNew('oxWrapping');
2138  $oCard->load($sCardId);
2139  $oCard->setWrappingVat($this->getAdditionalServicesVatPercent());
2140  }
2141 
2142  return $oCard;
2143  }
2144 
2150  public function getTotalDiscount()
2151  {
2152  return $this->_oTotalDiscount;
2153  }
2154 
2160  public function getDiscounts()
2161  {
2162  if ($this->getTotalDiscount() && $this->getTotalDiscount()->getBruttoPrice() == 0 && count($this->_aItemDiscounts) == 0) {
2163  return null;
2164  }
2165 
2166  return array_merge($this->_aItemDiscounts, $this->_aDiscounts);
2167  }
2168 
2174  public function getVoucherDiscount()
2175  {
2176  if ($this->getConfig()->getConfigParam('bl_showVouchers')) {
2177  return $this->_oVoucherDiscount;
2178  }
2179 
2180  return null;
2181  }
2182 
2188  public function setBasketCurrency($oCurrency)
2189  {
2190  $this->_oCurrency = $oCurrency;
2191  }
2192 
2198  public function getBasketCurrency()
2199  {
2200  if ($this->_oCurrency === null) {
2201  $this->_oCurrency = $this->getConfig()->getActShopCurrencyObject();
2202  }
2203 
2204  return $this->_oCurrency;
2205  }
2206 
2212  public function setSkipVouchersChecking($blSkipChecking = null)
2213  {
2214  $this->_blSkipVouchersAvailabilityChecking = $blSkipChecking;
2215  }
2216 
2222  public function hasSkipedDiscount()
2223  {
2224  return $this->_blSkipDiscounts;
2225  }
2226 
2232  public function setSkipDiscounts($blSkip)
2233  {
2234  $this->_blSkipDiscounts = $blSkip;
2235  }
2236 
2244  public function getProductsNetPrice()
2245  {
2246  return oxRegistry::getLang()->formatCurrency($this->getNettoSum(), $this->getBasketCurrency());
2247  }
2248 
2256  public function getFProductsPrice()
2257  {
2258  return oxRegistry::getLang()->formatCurrency($this->getBruttoSum(), $this->getBasketCurrency());
2259  }
2260 
2268  public function getDelCostVatPercent()
2269  {
2270  return $this->getCosts('oxdelivery')->getVat();
2271  }
2272 
2280  public function getDelCostVat()
2281  {
2282  $dDelVAT = $this->getCosts('oxdelivery')->getVatValue();
2283 
2284  // blShowVATForDelivery option will be used, only for displaying, but not calculation
2285  if ($dDelVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForDelivery')) {
2286  return oxRegistry::getLang()->formatCurrency($dDelVAT, $this->getBasketCurrency());
2287  }
2288 
2289  return false;
2290  }
2291 
2299  public function getDelCostNet()
2300  {
2301  $oConfig = $this->getConfig();
2302 
2303  // blShowVATForDelivery option will be used, only for displaying, but not calculation
2304  if ($oConfig->getConfigParam('blShowVATForDelivery') && ($this->getBasketUser() || $oConfig->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
2305  $dNetPrice = $this->getCosts('oxdelivery')->getNettoPrice();
2306  if ($dNetPrice > 0) {
2307  return oxRegistry::getLang()->formatCurrency($dNetPrice, $this->getBasketCurrency());
2308  }
2309  }
2310 
2311  return false;
2312  }
2313 
2321  public function getPayCostVatPercent()
2322  {
2323  return $this->getCosts('oxpayment')->getVat();
2324  }
2325 
2333  public function getPayCostVat()
2334  {
2335  $dPayVAT = $this->getCosts('oxpayment')->getVatValue();
2336 
2337  // blShowVATForPayCharge option will be used, only for displaying, but not calculation
2338  if ($dPayVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
2339  return oxRegistry::getLang()->formatCurrency($dPayVAT, $this->getBasketCurrency());
2340  }
2341 
2342  return false;
2343  }
2344 
2352  public function getPayCostNet()
2353  {
2354  // blShowVATForPayCharge option will be used, only for displaying, but not calculation
2355  if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
2356  $oPaymentCost = $this->getCosts('oxpayment');
2357  if ($oPaymentCost && $oPaymentCost->getNettoPrice()) {
2358  return oxRegistry::getLang()->formatCurrency($this->getCosts('oxpayment')->getNettoPrice(), $this->getBasketCurrency());
2359  }
2360  }
2361 
2362  return false;
2363  }
2364 
2372  public function getPaymentCosts()
2373  {
2374  $oPaymentCost = $this->getCosts('oxpayment');
2375  if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
2376  return $oPaymentCost->getBruttoPrice();
2377  }
2378  }
2379 
2385  public function getPaymentCost()
2386  {
2387  return $this->getCosts('oxpayment');
2388  }
2389 
2397  public function getFPaymentCosts()
2398  {
2399  $oPaymentCost = $this->getCosts('oxpayment');
2400  if ($oPaymentCost && $oPaymentCost->getBruttoPrice()) {
2401  return oxRegistry::getLang()->formatCurrency($oPaymentCost->getBruttoPrice(), $this->getBasketCurrency());
2402  }
2403 
2404  return false;
2405  }
2406 
2412  public function getVoucherDiscValue()
2413  {
2414  if ($this->getVoucherDiscount()) {
2415  return $this->getVoucherDiscount()->getBruttoPrice();
2416  }
2417 
2418  return false;
2419  }
2420 
2428  public function getFVoucherDiscountValue()
2429  {
2430  if ($oVoucherDiscount = $this->getVoucherDiscount()) {
2431  if ($oVoucherDiscount->getBruttoPrice()) {
2432  return oxRegistry::getLang()->formatCurrency($oVoucherDiscount->getBruttoPrice(), $this->getBasketCurrency());
2433  }
2434  }
2435 
2436  return false;
2437  }
2438 
2439 
2447  public function getWrappCostVatPercent()
2448  {
2449  return $this->getCosts('oxwrapping')->getVat();
2450  }
2451 
2452 
2460  public function getGiftCardCostVatPercent()
2461  {
2462  return $this->getCosts('oxgiftcard')->getVat();
2463  }
2464 
2472  public function getWrappCostVat()
2473  {
2474  // blShowVATForWrapping option will be used, only for displaying, but not calculation
2475  if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
2476  $oPrice = $this->getCosts('oxwrapping');
2477 
2478  if ($oPrice && $oPrice->getVatValue() > 0) {
2479  return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
2480  }
2481  }
2482 
2483  return false;
2484  }
2485 
2493  public function getWrappCostNet()
2494  {
2495  // blShowVATForWrapping option will be used, only for displaying, but not calculation
2496  if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
2497  $oPrice = $this->getCosts('oxwrapping');
2498 
2499  if ($oPrice && $oPrice->getNettoPrice() > 0) {
2500  return oxRegistry::getLang()->formatCurrency($oPrice->getNettoPrice(), $this->getBasketCurrency());
2501  }
2502  }
2503 
2504  return false;
2505  }
2506 
2514  public function getFWrappingCosts()
2515  {
2516  $oPrice = $this->getCosts('oxwrapping');
2517 
2518  if ($oPrice && $oPrice->getBruttoPrice()) {
2519  return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
2520  }
2521 
2522  return false;
2523  }
2524 
2530  public function getWrappingCost()
2531  {
2532  return $this->getCosts('oxwrapping');
2533  }
2534 
2542  public function getGiftCardCostVat()
2543  {
2544  // blShowVATForWrapping option will be used, only for displaying, but not calculation
2545  if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
2546  $oPrice = $this->getCosts('oxgiftcard');
2547 
2548  if ($oPrice && $oPrice->getVatValue() > 0) {
2549  return oxRegistry::getLang()->formatCurrency($oPrice->getVatValue(), $this->getBasketCurrency());
2550  }
2551  }
2552 
2553  return false;
2554 
2555  }
2556 
2564  public function getGiftCardCostNet()
2565  {
2566  // blShowVATForWrapping option will be used, only for displaying, but not calculation
2567  if ($this->getConfig()->getConfigParam('blShowVATForWrapping')) {
2568  $oPrice = $this->getCosts('oxgiftcard');
2569 
2570  if ($oPrice && $oPrice->getNettoPrice() > 0) {
2571  return oxRegistry::getLang()->formatCurrency($oPrice->getNettoPrice(), $this->getBasketCurrency());
2572  }
2573  }
2574 
2575  return false;
2576  }
2577 
2585  public function getFGiftCardCosts()
2586  {
2587  $oPrice = $this->getCosts('oxgiftcard');
2588 
2589  if ($oPrice && $oPrice->getBruttoPrice()) {
2590  return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
2591  }
2592 
2593  return false;
2594  }
2595 
2601  public function getGiftCardCost()
2602  {
2603  return $this->getCosts('oxgiftcard');
2604  }
2605 
2613  public function getFPrice()
2614  {
2615  return oxRegistry::getLang()->formatCurrency($this->getPrice()->getBruttoPrice(), $this->getBasketCurrency());
2616  }
2617 
2625  public function getFDeliveryCosts()
2626  {
2627  $oPrice = $this->getCosts('oxdelivery');
2628 
2629  if ($oPrice && ($this->getBasketUser() || $this->getConfig()->getConfigParam('blCalculateDelCostIfNotLoggedIn'))) {
2630  return oxRegistry::getLang()->formatCurrency($oPrice->getBruttoPrice(), $this->getBasketCurrency());
2631  }
2632 
2633  return false;
2634  }
2635 
2643  public function getDeliveryCosts()
2644  {
2645  if ($oDeliveryCost = $this->getCosts('oxdelivery')) {
2646  return $oDeliveryCost->getBruttoPrice();
2647  }
2648 
2649  return false;
2650  }
2651 
2657  public function getDeliveryCost()
2658  {
2659  return $this->getCosts('oxdelivery');
2660  }
2661 
2667  public function setTotalDiscount($dDiscount)
2668  {
2669  $this->_oTotalDiscount = oxNew('oxPrice');
2670  $this->_oTotalDiscount->setBruttoPriceMode();
2671  $this->_oTotalDiscount->add($dDiscount);
2672  }
2673 
2680  public function getPriceForPayment()
2681  {
2682  $dPrice = $this->getDiscountedProductsBruttoPrice();
2683  //#1905 not discounted products should be included in payment amount calculation
2684  if ($oPriceList = $this->getNotDiscountProductsPrice()) {
2685  $dPrice += $oPriceList->getBruttoSum();
2686  }
2687 
2688  // adding delivery price to final price
2689  if ($oDeliveryPrice = $this->_aCosts['oxdelivery']) {
2690  $dPrice += $oDeliveryPrice->getBruttoPrice();
2691  }
2692 
2693  return $dPrice;
2694  }
2695 
2696 
2702  public function _getDiscountedProductsSum()
2703  {
2704  if ($oProductsPrice = $this->getDiscountProductsPrice()) {
2705  $dPrice = $oProductsPrice->getSum($this->isCalculationModeNetto());
2706  }
2707 
2708  // subtracting total discount
2709  if ($oPrice = $this->getTotalDiscount()) {
2710  $dPrice -= $oPrice->getPrice();
2711  }
2712 
2713  if ($oVoucherPrice = $this->getVoucherDiscount()) {
2714  $dPrice -= $oVoucherPrice->getPrice();
2715  }
2716 
2717  return $dPrice;
2718  }
2719 
2725  public function getTotalDiscountSum()
2726  {
2727  $dPrice = 0;
2728  // subtracting total discount
2729  if ($oPrice = $this->getTotalDiscount()) {
2730  $dPrice += $oPrice->getPrice();
2731  }
2732 
2733  if ($oVoucherPrice = $this->getVoucherDiscount()) {
2734  $dPrice += $oVoucherPrice->getPrice();
2735  }
2736 
2737  return $dPrice;
2738  }
2739 
2746  {
2747  if ($oProductsPrice = $this->getDiscountProductsPrice()) {
2748  $dPrice = $oProductsPrice->getBruttoSum();
2749  }
2750 
2751  // subtracting total discount
2752  if ($oPrice = $this->getTotalDiscount()) {
2753  $dPrice -= $oPrice->getBruttoPrice();
2754  }
2755 
2756  if ($oVoucherPrice = $this->getVoucherDiscount()) {
2757  $dPrice -= $oVoucherPrice->getBruttoPrice();
2758  }
2759 
2760  return $dPrice;
2761  }
2762 
2768  public function isBelowMinOrderPrice()
2769  {
2770  $blIsBelowMinOrderPrice = false;
2771  $sConfValue = $this->getConfig()->getConfigParam('iMinOrderPrice');
2772  if (is_numeric($sConfValue) && $this->getProductsCount()) {
2773  $dMinOrderPrice = oxPrice::getPriceInActCurrency(( double ) $sConfValue);
2774  $dNotDiscountedProductPrice = 0;
2775  if ($oPrice = $this->getNotDiscountProductsPrice()) {
2776  $dNotDiscountedProductPrice = $oPrice->getBruttoSum();
2777  }
2778  $blIsBelowMinOrderPrice = ($dMinOrderPrice > ($this->getDiscountedProductsBruttoPrice() + $dNotDiscountedProductPrice));
2779  }
2780 
2781  return $blIsBelowMinOrderPrice;
2782 
2783  }
2784 
2793  public function getArtStockInBasket($sArtId, $sExpiredArtId = null)
2794  {
2795  $dArtStock = 0;
2796  foreach ($this->_aBasketContents as $sItemKey => $oOrderArticle) {
2797  if ($oOrderArticle && ($sExpiredArtId == null || $sExpiredArtId != $sItemKey)) {
2798  if ($oOrderArticle->getArticle(true)->getId() == $sArtId) {
2799  $dArtStock += $oOrderArticle->getAmount();
2800  }
2801  }
2802  }
2803 
2804  return $dArtStock;
2805  }
2806 
2814  public function canAddProductToBasket($sProductId)
2815  {
2816  $blCanAdd = null;
2817 
2818  // if basket category is not set..
2819  if ($this->_sBasketCategoryId === null) {
2820  $oCat = null;
2821 
2822  // request category
2823  if ($oView = $this->getConfig()->getActiveView()) {
2824  if ($oCat = $oView->getActiveCategory()) {
2825  if (!$this->_isProductInRootCategory($sProductId, $oCat->oxcategories__oxrootid->value)) {
2826  $oCat = null;
2827  } else {
2828  $blCanAdd = true;
2829  }
2830  }
2831  }
2832 
2833  // product main category
2834  if (!$oCat) {
2835  $oProduct = oxNew("oxArticle");
2836  if ($oProduct->load($sProductId)) {
2837  $oCat = $oProduct->getCategory();
2838  }
2839  }
2840 
2841  // root category id
2842  if ($oCat) {
2843  $this->setBasketRootCatId($oCat->oxcategories__oxrootid->value);
2844  }
2845  }
2846 
2847  // avoiding double check..
2848  if ($blCanAdd === null) {
2849  $blCanAdd = $this->_sBasketCategoryId ? $this->_isProductInRootCategory($sProductId, $this->getBasketRootCatId()) : true;
2850  }
2851 
2852  return $blCanAdd;
2853  }
2854 
2863  protected function _isProductInRootCategory($sProductId, $sRootCatId)
2864  {
2865  $sO2CTable = getViewName('oxobject2category');
2866  $sCatTable = getViewName('oxcategories');
2867 
2868  $oDb = oxDb::getDb();
2869  $sParentId = $oDb->getOne("select oxparentid from oxarticles where oxid = " . $oDb->quote($sProductId));
2870  $sProductId = $sParentId ? $sParentId : $sProductId;
2871 
2872  $sQ = "select 1 from {$sO2CTable}
2873  left join {$sCatTable} on {$sCatTable}.oxid = {$sO2CTable}.oxcatnid
2874  where {$sO2CTable}.oxobjectid = " . $oDb->quote($sProductId) . " and
2875  {$sCatTable}.oxrootid = " . $oDb->quote($sRootCatId);
2876 
2877  return (bool) $oDb->getOne($sQ);
2878  }
2879 
2885  public function setBasketRootCatId($sRoot)
2886  {
2887  $this->_sBasketCategoryId = $sRoot;
2888  }
2889 
2895  public function getBasketRootCatId()
2896  {
2898  }
2899 
2905  public function setCatChangeWarningState($blShow)
2906  {
2907  $this->_blShowCatChangeWarning = $blShow;
2908  }
2909 
2915  public function showCatChangeWarning()
2916  {
2918  }
2919 
2925  public function setTsProductId($sProductId)
2926  {
2927  $this->_sTsProductId = $sProductId;
2928  }
2929 
2935  public function getTsProductId()
2936  {
2937  return $this->_sTsProductId;
2938  }
2939 
2947  public function getFTsProtectionCosts()
2948  {
2949  $oProtectionCost = $this->getCosts('oxtsprotection');
2950  if ($oProtectionCost && $oProtectionCost->getBruttoPrice()) {
2951  return oxRegistry::getLang()->formatCurrency($oProtectionCost->getBruttoPrice(), $this->getBasketCurrency());
2952  }
2953 
2954  return false;
2955  }
2956 
2964  public function getTsProtectionVatPercent()
2965  {
2966  return $this->getCosts('oxtsprotection')->getVat();
2967  }
2968 
2976  public function getTsProtectionVat()
2977  {
2978  $dProtectionVAT = $this->getCosts('oxtsprotection')->getVatValue();
2979  // blShowVATForPayCharge option will be used, only for displaying, but not calculation
2980  if ($dProtectionVAT > 0 && $this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
2981  return oxRegistry::getLang()->formatCurrency($dProtectionVAT, $this->getBasketCurrency());
2982  }
2983 
2984  return false;
2985  }
2986 
2994  public function getTsProtectionNet()
2995  {
2996  // blShowVATForPayCharge option will be used, only for displaying, but not calculation
2997  if ($this->getConfig()->getConfigParam('blShowVATForPayCharge')) {
2998  return oxRegistry::getLang()->formatCurrency($this->getCosts('oxtsprotection')->getNettoPrice(), $this->getBasketCurrency());
2999  }
3000 
3001  return false;
3002  }
3003 
3011  public function getTsProtectionCosts()
3012  {
3013  $oProtection = $this->getCosts('oxtsprotection');
3014  if ($oProtection) {
3015  return $oProtection->getBruttoPrice();
3016  }
3017 
3018  return false;
3019  }
3020 
3027  {
3028  return $this->getCosts('oxtsprotection');
3029  }
3030 
3031 
3038  {
3040  }
3041 
3053  protected function _addedNewItem($sProductID, $dAmount, $aSel, $aPersParam, $blOverride, $blBundle, $sOldBasketItemId)
3054  {
3055  if (!$blOverride) {
3056  $this->_blNewITemAdded = null;
3057  oxRegistry::getSession()->setVariable("blAddedNewItem", true);
3058  }
3059  }
3060 
3064  public function __wakeUp()
3065  {
3066  $this->_blNewITemAdded = null;
3067  $this->_isCalculationModeNetto = null;
3068  }
3069 
3075  public function isNewItemAdded()
3076  {
3077  if ($this->_blNewITemAdded == null) {
3078  $this->_blNewITemAdded = (bool) oxRegistry::getSession()->getVariable("blAddedNewItem");
3079  oxRegistry::getSession()->deleteVariable("blAddedNewItem");
3080  }
3081 
3082  return $this->_blNewITemAdded;
3083  }
3084 
3090  public function hasDownloadableProducts()
3091  {
3092  $this->_blDownloadableProducts = false;
3094  foreach ($this->_aBasketContents as $oBasketItem) {
3095  if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->isDownloadable()) {
3096  $this->_blDownloadableProducts = true;
3097  break;
3098  }
3099  }
3100 
3102  }
3103 
3109  public function hasArticlesWithIntangibleAgreement()
3110  {
3111  $blHasArticlesWithIntangibleAgreement = false;
3112 
3114  foreach ($this->_aBasketContents as $oBasketItem) {
3115  if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasIntangibleAgreement()) {
3116  $blHasArticlesWithIntangibleAgreement = true;
3117  break;
3118  }
3119  }
3120 
3121  return $blHasArticlesWithIntangibleAgreement;
3122  }
3123 
3129  public function hasArticlesWithDownloadableAgreement()
3130  {
3131  $blHasArticlesWithIntangibleAgreement = false;
3132 
3134  foreach ($this->_aBasketContents as $oBasketItem) {
3135  if ($oBasketItem->getArticle(false) && $oBasketItem->getArticle(false)->hasDownloadableAgreement()) {
3136  $blHasArticlesWithIntangibleAgreement = true;
3137  break;
3138  }
3139  }
3140 
3141  return $blHasArticlesWithIntangibleAgreement;
3142  }
3143 
3149  public function getMinOrderPrice()
3150  {
3151  return oxPrice::getPriceInActCurrency($this->getConfig()->getConfigParam('iMinOrderPrice'));
3152  }
3153 
3159  public function getTsInsuredSum()
3160  {
3161  return $this->getPrice()->getBruttoPrice() - $this->getCosts('oxtsprotection')->getBruttoPrice();
3162  }
3163 }