oxdiscount.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class oxDiscount extends oxI18n
00008 {
00009 
00015     protected $_sClassName = 'oxdiscount';
00016 
00022     protected $_dAmount = null;
00023 
00029     protected $_sBasketIdent = null;
00030 
00036     protected $_blIsForArticleOrForCategory = null;
00037 
00043     protected $_aHasArticleDiscounts = array();
00044 
00048     public function __construct()
00049     {
00050         parent::__construct();
00051         $this->init('oxdiscount');
00052     }
00053 
00061     public function delete($sOXID = null)
00062     {
00063         if (!$sOXID) {
00064             $sOXID = $this->getId();
00065         }
00066         if (!$sOXID) {
00067             return false;
00068         }
00069 
00070 
00071         $oDb = oxDb::getDb();
00072         $oDb->execute('delete from oxobject2discount where oxobject2discount.oxdiscountid = ' . $oDb->quote($sOXID));
00073 
00074         return parent::delete($sOXID);
00075     }
00076 
00082     public function isGlobalDiscount()
00083     {
00084         if (is_null($this->_blIsForArticleOrForCategory)) {
00085             $oDb = oxDb::getDb();
00086             $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
00087 
00088             $sQuery = "select 1
00089                         from oxobject2discount
00090                         where oxdiscountid = $sDiscountIdQuoted and (oxtype = 'oxarticles' or oxtype = 'oxcategories')";
00091 
00092             $this->_blIsForArticleOrForCategory = $oDb->getOne($sQuery) ? false : true;
00093         }
00094 
00095         return $this->_blIsForArticleOrForCategory;
00096     }
00097 
00105     public function isForArticle($oArticle)
00106     {
00107         // item discounts may only be applied for basket
00108         if ($this->oxdiscount__oxaddsumtype->value == 'itm') {
00109             return false;
00110         }
00111 
00112         if ($this->oxdiscount__oxamount->value || $this->oxdiscount__oxprice->value) {
00113             return false;
00114         }
00115 
00116         if ($this->oxdiscount__oxpriceto->value && ($this->oxdiscount__oxpriceto->value < $oArticle->getBasePrice())) {
00117             return false;
00118         }
00119 
00120         if ($this->isGlobalDiscount()) {
00121             return true;
00122         }
00123 
00124         $sArticleId = $oArticle->getProductId();
00125 
00126         if (!isset($this->_aHasArticleDiscounts[$sArticleId])) {
00127 
00128             $blResult = $this->_isArticleAssigned($oArticle) || $this->_isCategoriesAssigned($oArticle->getCategoryIds());
00129 
00130             $this->_aHasArticleDiscounts[$sArticleId] = $blResult;
00131         }
00132 
00133         return $this->_aHasArticleDiscounts[$sArticleId];
00134     }
00135 
00143     public function isForBasketItem($oArticle)
00144     {
00145         if ($this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0) {
00146             return false;
00147         }
00148 
00149         // skipping bundle discounts
00150         if ($this->oxdiscount__oxaddsumtype->value == 'itm') {
00151             return false;
00152         }
00153 
00154         $oDb = oxDb::getDb();
00155 
00156         // check if this article is assigned
00157         $sQ = "select 1 from oxobject2discount where oxdiscountid = " . $oDb->quote($this->oxdiscount__oxid->value) . " and oxtype = 'oxarticles' ";
00158         $sQ .= $this->_getProductCheckQuery($oArticle);
00159         if (!($blOk = ( bool ) $oDb->getOne($sQ))) {
00160 
00161             // checking article category
00162             $blOk = $this->_checkForArticleCategories($oArticle);
00163         }
00164 
00165         return $blOk;
00166     }
00167 
00175     public function isForBasketAmount($oBasket)
00176     {
00177         $dAmount = 0;
00178         $aBasketItems = $oBasket->getContents();
00179         foreach ($aBasketItems as $oBasketItem) {
00180 
00181             $oBasketArticle = $oBasketItem->getArticle(false);
00182 
00183             $blForBasketItem = false;
00184             if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
00185                 $blForBasketItem = $this->isForBasketItem($oBasketArticle);
00186             } else {
00187                 $blForBasketItem = $this->isForBundleItem($oBasketArticle);
00188             }
00189 
00190             if ($blForBasketItem) {
00191                 $dRate = $oBasket->getBasketCurrency()->rate;
00192                 if ($this->oxdiscount__oxprice->value) {
00193                     if (($oPrice = $oBasketArticle->getPrice())) {
00194                         $dAmount += ($oPrice->getPrice() * $oBasketItem->getAmount()) / $dRate;
00195                     }
00196                 } elseif ($this->oxdiscount__oxamount->value) {
00197                     $dAmount += $oBasketItem->getAmount();
00198                 }
00199             }
00200         }
00201 
00202         return $this->isForAmount($dAmount);
00203     }
00204 
00212     public function isForAmount($dAmount)
00213     {
00214         $blIs = true;
00215 
00216         if ($this->oxdiscount__oxprice->value &&
00217             ($dAmount < $this->oxdiscount__oxprice->value || $dAmount > $this->oxdiscount__oxpriceto->value)
00218         ) {
00219             $blIs = false;
00220         } elseif ($this->oxdiscount__oxamount->value &&
00221                   ($dAmount < $this->oxdiscount__oxamount->value || $dAmount > $this->oxdiscount__oxamountto->value)
00222         ) {
00223             $blIs = false;
00224         }
00225 
00226         return $blIs;
00227     }
00228 
00236     public function isForBasket($oBasket)
00237     {
00238         // initial configuration check
00239         if ($this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0) {
00240             return false;
00241         }
00242 
00243         $oSummary = $oBasket->getBasketSummary();
00244         // amounts check
00245         if ($this->oxdiscount__oxamount->value && ($oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value)) {
00246             return false;
00247             // price check
00248         } elseif ($this->oxdiscount__oxprice->value) {
00249             $dRate = $oBasket->getBasketCurrency()->rate;
00250             if ($oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value * $dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value * $dRate) {
00251                 return false;
00252             }
00253         }
00254 
00255         // oxobject2discount configuration check
00256         $oDb = oxDb::getDb();
00257         $sQ = 'select 1 from oxobject2discount where oxdiscountid = ' . $oDb->quote($this->oxdiscount__oxid->value) . ' and oxtype in ("oxarticles", "oxcategories" ) ';
00258 
00259         return !((bool) $oDb->getOne($sQ));
00260     }
00261 
00269     public function isForBundleItem($oArticle)
00270     {
00271         if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
00272             return false;
00273         }
00274 
00275         $oDb = oxDb::getDb();
00276         $sQ = "select 1 from oxobject2discount where oxdiscountid=" . $oDb->quote($this->getId());
00277         $sQ .= $this->_getProductCheckQuery($oArticle);
00278         if (!($blOk = (bool) $oDb->getOne($sQ))) {
00279             // additional checks for amounts and other dependencies
00280             $blOk = $this->_checkForArticleCategories($oArticle);
00281         }
00282 
00283         return $blOk;
00284     }
00285 
00293     public function isForBundleBasket($oBasket)
00294     {
00295         if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
00296             return false;
00297         }
00298 
00299         return $this->isForBasket($oBasket);
00300     }
00301 
00310     public function getAbsValue($dPrice, $dAmount = 1)
00311     {
00312         if ($this->oxdiscount__oxaddsumtype->value == '%') {
00313             return $dPrice * ($this->oxdiscount__oxaddsum->value / 100);
00314         } else {
00315             $oCur = $this->getConfig()->getActShopCurrencyObject();
00316 
00317             return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
00318         }
00319     }
00320 
00328     public function getPercentage($dPrice)
00329     {
00330         if ($this->getAddSumType() == 'abs' && $dPrice > 0) {
00331             return $this->getAddSum() / $dPrice * 100;
00332         } else {
00333             return $this->getAddSum();
00334         }
00335     }
00336 
00343     public function getAddSum()
00344     {
00345         if ($this->oxdiscount__oxaddsumtype->value == 'abs') {
00346             $oCur = $this->getConfig()->getActShopCurrencyObject();
00347 
00348             return $this->oxdiscount__oxaddsum->value * $oCur->rate;
00349         } else {
00350             return $this->oxdiscount__oxaddsum->value;
00351         }
00352     }
00353 
00359     public function getAddSumType()
00360     {
00361         return $this->oxdiscount__oxaddsumtype->value;
00362     }
00363 
00371     public function getBundleAmount($dAmount)
00372     {
00373         $dItemAmount = $this->oxdiscount__oxitmamount->value;
00374 
00375         // Multiplying bundled articles count, if allowed
00376         if ($this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0) {
00377             $dItemAmount = floor($dAmount / $this->oxdiscount__oxamount->value) * $this->oxdiscount__oxitmamount->value;
00378         }
00379 
00380         return $dItemAmount;
00381     }
00382 
00388     public function getSimpleDiscount()
00389     {
00390         $oDiscount = new stdClass();
00391         $oDiscount->sOXID = $this->getId();
00392         $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
00393         $oDiscount->sType = $this->oxdiscount__oxaddsumtype->value;
00394 
00395         return $oDiscount;
00396     }
00397 
00403     public function getArticleIds()
00404     {
00405         return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '" . $this->getId() . "' and oxtype = 'oxarticles'");
00406     }
00407 
00413     public function getCategoryIds()
00414     {
00415         return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '" . $this->getId() . "' and oxtype = 'oxcategories'");
00416     }
00417 
00418 
00426     protected function _checkForArticleCategories($oArticle)
00427     {
00428         // check if article is in some assigned category
00429         $aCatIds = $oArticle->getCategoryIds();
00430         if (!$aCatIds || !count($aCatIds)) {
00431             // no categories are set for article, so no discounts from categories..
00432             return false;
00433         }
00434 
00435         $sCatIds = "(" . implode(",", oxDb::getInstance()->quoteArray($aCatIds)) . ")";
00436 
00437         $oDb = oxDb::getDb();
00438         // getOne appends limit 1, so this one should be fast enough
00439         $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = " . $oDb->quote($this->oxdiscount__oxid->value) . " and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00440 
00441         return $oDb->getOne($sQ);
00442     }
00443 
00452     protected function _getProductCheckQuery($oProduct)
00453     {
00454         $oDb = oxDb::getDb();
00455         // check if this article is assigned
00456         if (($sParentId = $oProduct->getParentId())) {
00457             $sArticleId = " and ( oxobjectid = " . $oDb->quote($oProduct->getProductId()) . " or oxobjectid = " . $oDb->quote($sParentId) . " )";
00458         } else {
00459             $sArticleId = " and oxobjectid = " . $oDb->quote($oProduct->getProductId());
00460         }
00461 
00462         return $sArticleId;
00463     }
00464 
00472     protected function _isArticleAssigned($oArticle)
00473     {
00474         $oDb = oxDb::getDb();
00475         $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
00476 
00477         $sQ = "select 1
00478                 from oxobject2discount
00479                 where oxdiscountid = {$sDiscountIdQuoted} and oxtype = 'oxarticles' ";
00480         $sQ .= $this->_getProductCheckQuery($oArticle);
00481 
00482         return $oDb->getOne($sQ) ? true : false;
00483     }
00484 
00492     protected function _isCategoriesAssigned($aCategoryIds)
00493     {
00494         if (empty($aCategoryIds)) {
00495             return false;
00496         }
00497 
00498         $oDb = oxDb::getDb();
00499         $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
00500 
00501         $sCategoryIds = "(" . implode(",", oxDb::getInstance()->quoteArray($aCategoryIds)) . ")";
00502         $sQ = "select 1
00503                 from oxobject2discount
00504                 where oxdiscountid = {$sDiscountIdQuoted} and oxobjectid in {$sCategoryIds} and oxtype = 'oxcategories'";
00505 
00506         return $oDb->getOne($sQ) ? true : false;
00507     }
00508 }