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         if ($oProduct->isOrderArticle()) {
00200             $oProduct = $oProduct->getArticle();
00201         }
00202 
00203         $blExclNonMaterial = $this->getConfig()->getConfigParam('blExclNonMaterialFromDelivery');
00204 
00205         // mark free shipping products
00206         if ($oProduct->oxarticles__oxfreeshipping->value || ($oProduct->oxarticles__oxnonmaterial->value && $blExclNonMaterial)) {
00207             if ($this->_blFreeShipping !== false) {
00208                 $this->_blFreeShipping = true;
00209             }
00210         } else {
00211 
00212             $this->_blFreeShipping = false;
00213 
00214             switch ($this->getConditionType()) {
00215                 case self::CONDITION_TYPE_PRICE: // price
00216                     if ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00217                         $dAmount += $oProduct->getPrice()->getPrice();
00218                     } else {
00219                         $dAmount += $oBasketItem->getPrice()->getPrice(); // price// currency conversion must allready be done in price class / $oCur->rate; // $oBasketItem->oPrice->getPrice() / $oCur->rate;
00220                     }
00221                     break;
00222                 case self::CONDITION_TYPE_WEIGHT: // weight
00223                     if ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00224                         $dAmount += $oProduct->getWeight();
00225                     } else {
00226                         $dAmount += $oBasketItem->getWeight();
00227                     }
00228                     break;
00229                 case self::CONDITION_TYPE_SIZE: // size
00230                     $dAmount += $oProduct->getSize();
00231                     if ($this->getCalculationRule() != self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00232                         $dAmount *= $oBasketItem->getAmount();
00233                     }
00234                     break;
00235                 case self::CONDITION_TYPE_AMOUNT: // amount
00236                     $dAmount += $oBasketItem->getAmount();
00237                     break;
00238             }
00239 
00240             if ($oBasketItem->getPrice()) {
00241                 $this->_dPrice += $oBasketItem->getPrice()->getPrice();
00242             }
00243         }
00244 
00245         return $dAmount;
00246     }
00247 
00253     public function setDeliveryPrice($oPrice)
00254     {
00255         $this->_oPrice = $oPrice;
00256     }
00257 
00265     public function getDeliveryPrice($dVat = null)
00266     {
00267         if ($this->_oPrice === null) {
00268 
00269             // loading oxPrice object for final price calculation
00270             $oPrice = oxNew('oxPrice');
00271             $oPrice->setNettoMode($this->_blDelVatOnTop);
00272             $oPrice->setVat($dVat);
00273 
00274             // if article is free shipping, price for delivery will be not calculated
00275             if (!$this->_blFreeShipping) {
00276                 $oPrice->add($this->_getCostSum());
00277             }
00278             $this->setDeliveryPrice($oPrice);
00279         }
00280 
00281         return $this->_oPrice;
00282     }
00283 
00291     public function delete($sOxId = null)
00292     {
00293         if (!$sOxId) {
00294             $sOxId = $this->getId();
00295         }
00296         if (!$sOxId) {
00297             return false;
00298         }
00299 
00300 
00301         $oDb = oxDb::getDb();
00302         $sQ = "delete from `oxobject2delivery` where `oxobject2delivery`.`oxdeliveryid` = " . $oDb->quote($sOxId);
00303         $oDb->execute($sQ);
00304 
00305         return parent::delete($sOxId);
00306     }
00307 
00315     public function isForBasket($oBasket)
00316     {
00317         // amount for conditional check
00318         $blHasArticles = $this->hasArticles();
00319         $blHasCategories = $this->hasCategories();
00320         $blUse = true;
00321         $iAmount = 0;
00322         $blForBasket = false;
00323 
00324         // category & article check
00325         if ($blHasCategories || $blHasArticles) {
00326             $blUse = false;
00327 
00328             $aDeliveryArticles = $this->getArticles();
00329             $aDeliveryCategories = $this->getCategories();
00330 
00331             foreach ($oBasket->getContents() as $oContent) {
00332 
00333                 //V FS#1954 - load delivery for variants from parent article
00334                 $oArticle = $oContent->getArticle(false);
00335                 $sProductId = $oArticle->getProductId();
00336                 $sParentId = $oArticle->getParentId();
00337 
00338                 if ($blHasArticles && (in_array($sProductId, $aDeliveryArticles) || ($sParentId && in_array($sParentId, $aDeliveryArticles)))) {
00339                     $blUse = true;
00340                     $iArtAmount = $this->getDeliveryAmount($oContent);
00341                     if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00342                         if ($this->_isForArticle($oContent, $iArtAmount)) {
00343                             $blForBasket = true;
00344                         }
00345                     }
00346                     if (!$blForBasket) {
00347                         $iAmount += $iArtAmount;
00348                     }
00349 
00350                 } elseif ($blHasCategories) {
00351 
00352                     if (isset(self::$_aProductList[$sProductId])) {
00353                         $oProduct = self::$_aProductList[$sProductId];
00354                     } else {
00355                         $oProduct = oxNew('oxArticle');
00356                         $oProduct->setSkipAssign(true);
00357 
00358                         if (!$oProduct->load($sProductId)) {
00359                             continue;
00360                         }
00361 
00362                         $oProduct->setId($sProductId);
00363                         self::$_aProductList[$sProductId] = $oProduct;
00364                     }
00365 
00366                     foreach ($aDeliveryCategories as $sCatId) {
00367 
00368                         if ($oProduct->inCategory($sCatId)) {
00369                             $blUse = true;
00370                             $iArtAmount = $this->getDeliveryAmount($oContent);
00371                             if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00372                                 if ($this->_isForArticle($oContent, $iArtAmount)) {
00373                                     $blForBasket = true;
00374                                 }
00375                             }
00376                             if (!$blForBasket) {
00377                                 $iAmount += $iArtAmount;
00378                             }
00379                         }
00380                     }
00381 
00382                 }
00383             }
00384         } else {
00385             // regular amounts check
00386             foreach ($oBasket->getContents() as $oContent) {
00387                 $iArtAmount = $this->getDeliveryAmount($oContent);
00388                 if ($this->getCalculationRule() != self::CALCULATION_RULE_ONCE_PER_CART) {
00389                     if ($this->_isForArticle($oContent, $iArtAmount)) {
00390                         $blForBasket = true;
00391                     }
00392                 }
00393                 if (!$blForBasket) {
00394                     $iAmount += $iArtAmount;
00395                 }
00396             }
00397         }
00398 
00399         /* if ( $this->getConditionType() == self::CONDITION_TYPE_PRICE ) {
00400              $iAmount = $oBasket->_getDiscountedProductsSum();
00401          }*/
00402 
00403         //#M1130: Single article in Basket, checked as free shipping, is not buyable (step 3 no payments found)
00404         if (!$blForBasket && $blUse && ($this->_checkDeliveryAmount($iAmount) || $this->_blFreeShipping)) {
00405             $blForBasket = true;
00406         }
00407 
00408         return $blForBasket;
00409     }
00410 
00419     protected function _isForArticle($oContent, $iArtAmount)
00420     {
00421         $blResult = false;
00422         if (!$this->_blFreeShipping && $this->_checkDeliveryAmount($iArtAmount)) {
00423             $this->_iItemCnt += $oContent->getAmount();
00424             $this->_iProdCnt += 1;
00425             $blResult = true;
00426         }
00427 
00428         return $blResult;
00429     }
00430 
00438     protected function _checkDeliveryAmount($iAmount)
00439     {
00440         $blResult = false;
00441 
00442         if ($this->getConditionType() == self::CONDITION_TYPE_PRICE) {
00443             $oCur = $this->getConfig()->getActShopCurrencyObject();
00444             $iAmount /= $oCur->rate;
00445         }
00446 
00447         if ($iAmount >= $this->getConditionFrom() && $iAmount <= $this->getConditionTo()) {
00448             $blResult = true;
00449         }
00450 
00451         return $blResult;
00452     }
00453 
00461     public function getIdByName($sTitle)
00462     {
00463         $oDb = oxDb::getDb();
00464         $sQ = "SELECT `oxid` FROM `" . getViewName('oxdelivery') . "` WHERE `oxtitle` = " . $oDb->quote($sTitle);
00465         $sId = $oDb->getOne($sQ);
00466 
00467         return $sId;
00468     }
00469 
00475     public function getCountriesISO()
00476     {
00477         if ($this->_aCountriesISO === null) {
00478 
00479             $oDb = oxDb::getDb();
00480             $this->_aCountriesISO = array();
00481 
00482             $sSelect = "
00483                 SELECT
00484                     `oxcountry`.`oxisoalpha2`
00485                 FROM `oxcountry`
00486                     LEFT JOIN `oxobject2delivery` ON `oxobject2delivery`.`oxobjectid` = `oxcountry`.`oxid`
00487                 WHERE `oxobject2delivery`.`oxdeliveryid` = " . $oDb->quote($this->getId()) . "
00488                     AND `oxobject2delivery`.`oxtype` = 'oxcountry'";
00489 
00490             $rs = $oDb->getCol($sSelect);
00491             $this->_aCountriesISO = $rs;
00492 
00493         }
00494 
00495         return $this->_aCountriesISO;
00496     }
00497 
00503     public function getConditionType()
00504     {
00505         return $this->oxdelivery__oxdeltype->value;
00506     }
00507 
00513     public function getConditionFrom()
00514     {
00515         return $this->oxdelivery__oxparam->value;
00516     }
00517 
00523     public function getConditionTo()
00524     {
00525         return $this->oxdelivery__oxparamend->value;
00526     }
00527 
00533     public function getCalculationRule()
00534     {
00535         return $this->oxdelivery__oxfixed->value;
00536     }
00537 
00543     public function getAddSum()
00544     {
00545         return $this->oxdelivery__oxaddsum->value;
00546     }
00547 
00553     public function getAddSumType()
00554     {
00555         return $this->oxdelivery__oxaddsumtype->value;
00556     }
00557 
00563     protected function _getMultiplier()
00564     {
00565         $dAmount = 0;
00566 
00567         if ($this->getCalculationRule() == self::CALCULATION_RULE_ONCE_PER_CART) {
00568             $dAmount = 1;
00569         } elseif ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_DIFFERENT_PRODUCT) {
00570             $dAmount = $this->_iProdCnt;
00571         } elseif ($this->getCalculationRule() == self::CALCULATION_RULE_FOR_EACH_PRODUCT) {
00572             $dAmount = $this->_iItemCnt;
00573         }
00574 
00575         return $dAmount;
00576     }
00577 
00583     protected function _getCostSum()
00584     {
00585         if ($this->getAddSumType() == 'abs') {
00586             $oCur = $this->getConfig()->getActShopCurrencyObject();
00587             $dPrice = $this->getAddSum() * $oCur->rate * $this->_getMultiplier();
00588         } else {
00589             $dPrice = $this->_dPrice / 100 * $this->getAddSum();
00590         }
00591 
00592         return $dPrice;
00593     }
00594 }