oxdelivery.php

Go to the documentation of this file.
00001 <?php
00002 
00008 class oxDelivery extends oxI18n
00009 {
00010 
00014     const CALCULATION_RULE_ONCE_PER_CART = 0;
00015     const CALCULATION_RULE_FOR_EACH_DIFFERENT_PRODUCT = 1;
00016     const CALCULATION_RULE_FOR_EACH_PRODUCT = 2;
00017 
00021     const CONDITION_TYPE_PRICE = 'p';
00022     const CONDITION_TYPE_AMOUNT = 'a';
00023     const CONDITION_TYPE_SIZE = 's';
00024     const CONDITION_TYPE_WEIGHT = 'w';
00025 
00031     protected $_sClassName = 'oxdelivery';
00032 
00039     protected $_iItemCnt = 0;
00040 
00047     protected $_iProdCnt = 0;
00048 
00055     protected $_dPrice = 0;
00056 
00062     protected $_oPrice = null;
00063 
00069     protected $_aArtIds = null;
00070 
00076     protected $_aCatIds = null;
00077 
00083     protected $_blFreeShipping = true;
00084 
00090     protected static $_aProductList = array();
00091 
00097     protected $_blDelVatOnTop = false;
00098 
00104     protected $_aCountriesISO = null;
00105 
00111     protected $_aRDFaDeliverySet = null;
00112 
00116     public function __construct()
00117     {
00118         parent::__construct();
00119         $this->init('oxdelivery');
00120         $this->setDelVatOnTop($this->getConfig()->getConfigParam('blDeliveryVatOnTop'));
00121     }
00122 
00128     public function setDelVatOnTop($blOnTop)
00129     {
00130         $this->_blDelVatOnTop = $blOnTop;
00131     }
00132 
00138     public function getArticles()
00139     {
00140         if (is_null($this->_aArtIds)) {
00141             $oDb = oxDb::getDb();
00142             $sQ = "select oxobjectid from oxobject2delivery where oxdeliveryid=" . $oDb->quote($this->getId()) . " and oxtype = 'oxarticles'";
00143             $aArtIds = $oDb->getCol($sQ);
00144             $this->_aArtIds = $aArtIds;
00145         }
00146 
00147         return $this->_aArtIds;
00148     }
00149 
00155     public function getCategories()
00156     {
00157         if (is_null($this->_aCatIds)) {
00158             $oDb = oxDb::getDb();
00159             $sQ = "select oxobjectid from oxobject2delivery where oxdeliveryid=" . $oDb->quote($this->getId()) . " and oxtype = 'oxcategories'";
00160             $aCatIds = $oDb->getCol($sQ);
00161             $this->_aCatIds = $aCatIds;
00162         }
00163 
00164         return $this->_aCatIds;
00165     }
00166 
00172     public function hasArticles()
00173     {
00174         return ( bool ) count($this->getArticles());
00175     }
00176 
00182     public function hasCategories()
00183     {
00184         return ( bool ) count($this->getCategories());
00185     }
00186 
00194     public function getDeliveryAmount($oBasketItem)
00195     {
00196         $dAmount = 0;
00197         $oProduct = $oBasketItem->getArticle(false);
00198 
00199         $blExclNonMaterial = $this->getConfig()->getConfigParam('blExclNonMaterialFromDelivery');
00200 
00201         // mark free shipping products
00202         if ($oProduct->oxarticles__oxfreeshipping->value || ($oProduct->oxarticles__oxnonmaterial->value && $blExclNonMaterial)) {
00203             if ($this->_blFreeShipping !== false) {
00204                 $this->_blFreeShipping = true;
00205             }
00206         } else {
00207 
00208             $this->_blFreeShipping = false;
00209 
00210             switch ($this->getConditionType()) {
00211                 case self::CONDITION_TYPE_PRICE: // price
00212                     if ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00213                         $dAmount += $oProduct->getPrice()->getPrice();
00214                     } else {
00215                         $dAmount += $oBasketItem->getPrice()->getPrice(); // price// currency conversion must allready be done in price class / $oCur->rate; // $oBasketItem->oPrice->getPrice() / $oCur->rate;
00216                     }
00217                     break;
00218                 case self::CONDITION_TYPE_WEIGHT: // weight
00219                     if ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00220                         $dAmount += $oProduct->getWeight();
00221                     } else {
00222                         $dAmount += $oBasketItem->getWeight();
00223                     }
00224                     break;
00225                 case self::CONDITION_TYPE_SIZE: // size
00226                     $dAmount += $oProduct->getSize();
00227                     if ($this->getCalculationRule() != self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00228                         $dAmount *= $oBasketItem->getAmount();
00229                     }
00230                     break;
00231                 case self::CONDITION_TYPE_AMOUNT: // amount
00232                     $dAmount += $oBasketItem->getAmount();
00233                     break;
00234             }
00235 
00236             if ($oBasketItem->getPrice()) {
00237                 $this->_dPrice += $oBasketItem->getPrice()->getPrice();
00238             }
00239         }
00240 
00241         return $dAmount;
00242     }
00243 
00249     public function setDeliveryPrice($oPrice)
00250     {
00251         $this->_oPrice = $oPrice;
00252     }
00253 
00261     public function getDeliveryPrice($dVat = null)
00262     {
00263         if ($this->_oPrice === null) {
00264 
00265             // loading oxPrice object for final price calculation
00266             $oPrice = oxNew('oxPrice');
00267             $oPrice->setNettoMode($this->_blDelVatOnTop);
00268             $oPrice->setVat($dVat);
00269 
00270             // if article is free shipping, price for delivery will be not calculated
00271             if (!$this->_blFreeShipping) {
00272                 $oPrice->add($this->_getCostSum());
00273             }
00274             $this->setDeliveryPrice($oPrice);
00275         }
00276 
00277         return $this->_oPrice;
00278     }
00279 
00287     public function delete($sOxId = null)
00288     {
00289         if (!$sOxId) {
00290             $sOxId = $this->getId();
00291         }
00292         if (!$sOxId) {
00293             return false;
00294         }
00295 
00296 
00297         $oDb = oxDb::getDb();
00298         $sQ = "delete from `oxobject2delivery` where `oxobject2delivery`.`oxdeliveryid` = " . $oDb->quote($sOxId);
00299         $oDb->execute($sQ);
00300 
00301         return parent::delete($sOxId);
00302     }
00303 
00311     public function isForBasket($oBasket)
00312     {
00313         // amount for conditional check
00314         $blHasArticles = $this->hasArticles();
00315         $blHasCategories = $this->hasCategories();
00316         $blUse = true;
00317         $iAmount = 0;
00318         $blForBasket = false;
00319 
00320         // category & article check
00321         if ($blHasCategories || $blHasArticles) {
00322             $blUse = false;
00323 
00324             $aDeliveryArticles = $this->getArticles();
00325             $aDeliveryCategories = $this->getCategories();
00326 
00327             foreach ($oBasket->getContents() as $oContent) {
00328 
00329                 //V FS#1954 - load delivery for variants from parent article
00330                 $oArticle = $oContent->getArticle(false);
00331                 $sProductId = $oArticle->getProductId();
00332                 $sParentId = $oArticle->getParentId();
00333 
00334                 if ($blHasArticles && (in_array($sProductId, $aDeliveryArticles) || ($sParentId && in_array($sParentId, $aDeliveryArticles)))) {
00335                     $blUse = true;
00336                     $iArtAmount = $this->getDeliveryAmount($oContent);
00337                     if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00338                         if ($this->_isForArticle($oContent, $iArtAmount)) {
00339                             $blForBasket = true;
00340                         }
00341                     }
00342                     if (!$blForBasket) {
00343                         $iAmount += $iArtAmount;
00344                     }
00345 
00346                 } elseif ($blHasCategories) {
00347 
00348                     if (isset(self::$_aProductList[$sProductId])) {
00349                         $oProduct = self::$_aProductList[$sProductId];
00350                     } else {
00351                         $oProduct = oxNew('oxArticle');
00352                         $oProduct->setSkipAssign(true);
00353 
00354                         if (!$oProduct->load($sProductId)) {
00355                             continue;
00356                         }
00357 
00358                         $oProduct->setId($sProductId);
00359                         self::$_aProductList[$sProductId] = $oProduct;
00360                     }
00361 
00362                     foreach ($aDeliveryCategories as $sCatId) {
00363 
00364                         if ($oProduct->inCategory($sCatId)) {
00365                             $blUse = true;
00366                             $iArtAmount = $this->getDeliveryAmount($oContent);
00367                             if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00368                                 if ($this->_isForArticle($oContent, $iArtAmount)) {
00369                                     $blForBasket = true;
00370                                 }
00371                             }
00372                             if (!$blForBasket) {
00373                                 $iAmount += $iArtAmount;
00374                             }
00375                         }
00376                     }
00377 
00378                 }
00379             }
00380         } else {
00381             // regular amounts check
00382             foreach ($oBasket->getContents() as $oContent) {
00383                 $iArtAmount = $this->getDeliveryAmount($oContent);
00384                 if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00385                     if ($this->_isForArticle($oContent, $iArtAmount)) {
00386                         $blForBasket = true;
00387                     }
00388                 }
00389                 if (!$blForBasket) {
00390                     $iAmount += $iArtAmount;
00391                 }
00392             }
00393         }
00394 
00395         /* if ( $this->getConditionType() == self::CONDITION_TYPE_PRICE ) {
00396              $iAmount = $oBasket->_getDiscountedProductsSum();
00397          }*/
00398 
00399         //#M1130: Single article in Basket, checked as free shipping, is not buyable (step 3 no payments found)
00400         if (!$blForBasket && $blUse && ($this->_checkDeliveryAmount($iAmount) || $this->_blFreeShipping)) {
00401             $blForBasket = true;
00402         }
00403 
00404         return $blForBasket;
00405     }
00406 
00415     protected function _isForArticle($oContent, $iArtAmount)
00416     {
00417         $blResult = false;
00418         if (!$this->_blFreeShipping && $this->_checkDeliveryAmount($iArtAmount)) {
00419             $this->_iItemCnt += $oContent->getAmount();
00420             $this->_iProdCnt += 1;
00421             $blResult = true;
00422         }
00423 
00424         return $blResult;
00425     }
00426 
00434     protected function _checkDeliveryAmount($iAmount)
00435     {
00436         $blResult = false;
00437 
00438         if ($this->getConditionType() == self::CONDITION_TYPE_PRICE) {
00439             $oCur = $this->getConfig()->getActShopCurrencyObject();
00440             $iAmount /= $oCur->rate;
00441         }
00442 
00443         if ($iAmount >= $this->getConditionFrom() && $iAmount <= $this->getConditionTo()) {
00444             $blResult = true;
00445         }
00446 
00447         return $blResult;
00448     }
00449 
00457     public function getIdByName($sTitle)
00458     {
00459         $oDb = oxDb::getDb();
00460         $sQ = "SELECT `oxid` FROM `" . getViewName('oxdelivery') . "` WHERE `oxtitle` = " . $oDb->quote($sTitle);
00461         $sId = $oDb->getOne($sQ);
00462 
00463         return $sId;
00464     }
00465 
00471     public function getCountriesISO()
00472     {
00473         if ($this->_aCountriesISO === null) {
00474 
00475             $oDb = oxDb::getDb();
00476             $this->_aCountriesISO = array();
00477 
00478             $sSelect = "
00479                 SELECT
00480                     `oxcountry`.`oxisoalpha2`
00481                 FROM `oxcountry`
00482                     LEFT JOIN `oxobject2delivery` ON `oxobject2delivery`.`oxobjectid` = `oxcountry`.`oxid`
00483                 WHERE `oxobject2delivery`.`oxdeliveryid` = " . $oDb->quote($this->getId()) . "
00484                     AND `oxobject2delivery`.`oxtype` = 'oxcountry'";
00485 
00486             $rs = $oDb->getCol($sSelect);
00487             $this->_aCountriesISO = $rs;
00488 
00489         }
00490 
00491         return $this->_aCountriesISO;
00492     }
00493 
00499     public function getConditionType()
00500     {
00501         return $this->oxdelivery__oxdeltype->value;
00502     }
00503 
00509     public function getConditionFrom()
00510     {
00511         return $this->oxdelivery__oxparam->value;
00512     }
00513 
00519     public function getConditionTo()
00520     {
00521         return $this->oxdelivery__oxparamend->value;
00522     }
00523 
00529     public function getCalculationRule()
00530     {
00531         return $this->oxdelivery__oxfixed->value;
00532     }
00533 
00539     public function getAddSum()
00540     {
00541         return $this->oxdelivery__oxaddsum->value;
00542     }
00543 
00549     public function getAddSumType()
00550     {
00551         return $this->oxdelivery__oxaddsumtype->value;
00552     }
00553 
00559     protected function _getMultiplier()
00560     {
00561         $dAmount = 0;
00562 
00563         if ($this->getCalculationRule() == self::CALCULATION_RULE_ONCE_PER_CART) {
00564             $dAmount = 1;
00565         } elseif ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_DIFFERENT_PRODUCT) {
00566             $dAmount = $this->_iProdCnt;
00567         } elseif ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00568             $dAmount = $this->_iItemCnt;
00569         }
00570 
00571         return $dAmount;
00572     }
00573 
00579     protected function _getCostSum()
00580     {
00581         if ($this->getAddSumType() == 'abs') {
00582             $oCur = $this->getConfig()->getActShopCurrencyObject();
00583             $dPrice = $this->getAddSum() * $oCur->rate * $this->_getMultiplier();
00584         } else {
00585             $dPrice = $this->_dPrice / 100 * $this->getAddSum();
00586         }
00587 
00588         return $dPrice;
00589     }
00590 }