oxdiscount.php

Go to the documentation of this file.
00001 <?php
00002 
00006 class oxDiscount extends oxI18n
00007 {
00013     protected $_sClassName = 'oxdiscount';
00014 
00020     protected $_dAmount = null;
00021 
00027     protected $_sBasketIdent = null;
00028 
00032     public function __construct()
00033     {
00034         parent::__construct();
00035         $this->init( 'oxdiscount' );
00036     }
00037 
00045     public function delete( $sOXID = null )
00046     {
00047         if ( !$sOXID ) {
00048             $sOXID = $this->getId();
00049         }
00050         if ( !$sOXID ) {
00051             return false;
00052         }
00053 
00054 
00055         $oDB = oxDb::getDb();
00056         $oDB->execute( 'delete from oxobject2discount where oxobject2discount.oxdiscountid = '.$oDB->quote($sOXID) );
00057 
00058         return parent::delete( $sOXID );
00059     }
00060 
00068     public function isForArticle( $oArticle )
00069     {
00070         // item discounts may only be applied for basket
00071         if ( $this->oxdiscount__oxaddsumtype->value == 'itm' ) {
00072             return false;
00073         }
00074 
00075         if ( $this->oxdiscount__oxamount->value || $this->oxdiscount__oxprice->value ) {
00076             return false;
00077         }
00078 
00079         if ( $this->oxdiscount__oxpriceto->value && ($this->oxdiscount__oxpriceto->value < $oArticle->getBasePrice()) ) {
00080             return false;
00081         }
00082 
00083         $myDB = oxDb::getDb();
00084 
00085         $sDiscountIdQuoted = $myDB->quote($this->oxdiscount__oxid->value);
00086         //check for global discount (no articles, no categories)
00087         $sQ = "select 1 from oxobject2discount where oxdiscountid = $sDiscountIdQuoted and ( oxtype = 'oxarticles' or oxtype = 'oxcategories')";
00088         $blOk = (bool) $myDB->getOne( $sQ );
00089 
00090         if ( !$blOk ) {
00091             return true;
00092         }
00093 
00094         // check if this article is assigned
00095         $sArticleId = "";
00096         if ( $sParentId = $oArticle->getProductParentId() ) {
00097             $sArticleId = "(oxobjectid = '".$oArticle->getProductId()."' or oxobjectid = ".$myDB->quote($sParentId).")";
00098         } else {
00099             $sArticleId = "oxobjectid = '".$oArticle->getProductId()."'";
00100         }
00101 
00102         $sQ = "select 1 from oxobject2discount where oxdiscountid = $sDiscountIdQuoted and {$sArticleId} and oxtype = 'oxarticles'";
00103         $blOk = (bool) $myDB->getOne( $sQ );
00104         if ( $blOk ) {
00105             return true;
00106         } else {
00107             // check if article is in some assigned category
00108             $aCatIds = $oArticle->getCategoryIds();
00109             if (!$aCatIds || !count($aCatIds)) {
00110                 // no categories are set for article, so no discounts from categories..
00111                 return false;
00112             }
00113             $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
00114             // getOne appends limit 1, so this one should be fast enough
00115             $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = $sDiscountIdQuoted and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00116             if ( ( bool ) $myDB->getOne( $sQ ) ) {
00117                 return true;
00118             }
00119         }
00120         return false;
00121     }
00122 
00130     public function isForBasketItem( $oArticle )
00131     {
00132         if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
00133             return false;
00134         }
00135 
00136         // skipping bundle discounts
00137         if ( $this->oxdiscount__oxaddsumtype->value == 'itm' ) {
00138             return false;
00139         }
00140 
00141         $myDB = oxDb::getDb();
00142         // check if this article is assigned
00143         $sArticleId = "";
00144         if ( $sParentId = $oArticle->getProductParentId() ) {
00145             $sArticleId = "(oxobjectid = '".$oArticle->getProductId()."' or oxobjectid = '{$sParentId}')";
00146         } else {
00147             $sArticleId = "oxobjectid = '".$oArticle->getProductId()."'";
00148         }
00149         $sQ = "select 1 from oxobject2discount where oxdiscountid = '{$this->oxdiscount__oxid->value}' and ($sArticleId) and oxtype = 'oxarticles'";
00150         if ( !( $blOk = ( bool ) $myDB->getOne( $sQ ) ) ) {
00151 
00152             // checkin article cateogry
00153             $blOk = $this->_checkForArticleCategories( $oArticle );
00154         }
00155 
00156         return $blOk;
00157     }
00158 
00166     public function isForBasketAmount( $oBasket )
00167     {
00168         $dAmount = 0;
00169         $aBasketItems = $oBasket->getContents();
00170         foreach ( $aBasketItems as $oBasketItem ) {
00171 
00172             $oBasketArticle = $oBasketItem->getArticle(false);
00173 
00174             $blForBasketItem = false;
00175             if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00176                 $blForBasketItem = $this->isForBasketItem( $oBasketArticle );
00177             } else {
00178                 $blForBasketItem = $this->isForBundleItem( $oBasketArticle );
00179             }
00180 
00181             if ( $blForBasketItem ) {
00182                 $dRate = $oBasket->getBasketCurrency()->rate;
00183                 if ( $this->oxdiscount__oxprice->value ) {
00184                     if ( ( $oPrice = $oBasketArticle->getPrice() ) ) {
00185                         $dAmount += ($oPrice->getBruttoPrice() * $oBasketItem->getAmount())/$dRate;
00186                     }
00187                 } elseif ( $this->oxdiscount__oxamount->value ) {
00188                     $dAmount += $oBasketItem->getAmount();
00189                 }
00190             }
00191         }
00192 
00193         return $this->isForAmount( $dAmount );
00194     }
00195 
00203     public function isForAmount( $dAmount )
00204     {
00205         $blIs = true;
00206 
00207         if ( $this->oxdiscount__oxprice->value &&
00208             ( $dAmount < $this->oxdiscount__oxprice->value || $dAmount > $this->oxdiscount__oxpriceto->value ) ) {
00209             $blIs = false;
00210         } elseif ( $this->oxdiscount__oxamount->value &&
00211             ( $dAmount < $this->oxdiscount__oxamount->value || $dAmount > $this->oxdiscount__oxamountto->value ) ) {
00212             $blIs = false;
00213         }
00214         return $blIs;
00215     }
00216 
00224     public function isForBasket( $oBasket )
00225     {
00226         // initial configuration check
00227         if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
00228             return false;
00229         }
00230 
00231         $oSummary = $oBasket->getBasketSummary();
00232         // amounts check
00233         if ( $this->oxdiscount__oxamount->value && ( $oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value ) ) {
00234             return false;
00235             // price check
00236         } elseif ($this->oxdiscount__oxprice->value) {
00237             $dRate = $oBasket->getBasketCurrency()->rate;
00238             if ( $oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value*$dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value*$dRate ) {
00239                 return false;
00240             }
00241         }
00242 
00243         // oxobject2discount configuration check
00244         $sQ = 'select 1 from oxobject2discount where oxdiscountid = '.oxDb::getDb()->quote($this->oxdiscount__oxid->value).' and oxtype in ("oxarticles", "oxcategories" ) ';
00245 
00246         return !( (bool) oxDb::getDb()->getOne( $sQ ) );
00247     }
00248 
00256     public function isForBundleItem( $oArticle )
00257     {
00258         if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00259             return false;
00260         }
00261 
00262         $sSelect = "select 1 from oxobject2discount where oxdiscountid='".$this->getId()."' and oxobjectid='".$oArticle->getProductId()."' ";
00263         if ( !( $blOk = (bool) oxDb::getDb()->getOne( $sSelect ) ) ) {
00264             // additional checks for amounts and other dependencies
00265             $blOk = $this->_checkForArticleCategories( $oArticle );
00266         }
00267         return $blOk;
00268     }
00269 
00277     public function isForBundleBasket( $oBasket )
00278     {
00279         if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00280             return false;
00281         }
00282 
00283         return $this->isForBasket( $oBasket );
00284     }
00285 
00294     public function getAbsValue( $dPrice, $dAmount = 1 )
00295     {
00296         if ( $this->oxdiscount__oxaddsumtype->value == '%' ) {
00297             return $dPrice * ( $this->oxdiscount__oxaddsum->value / 100 );
00298         } else {
00299             $oCur = $this->getConfig()->getActShopCurrencyObject();
00300             return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
00301         }
00302     }
00303 
00312     public function applyDiscount( $oPrice, $dAmount = 1 )
00313     {
00314         if ( $this->oxdiscount__oxaddsumtype->value == 'abs' ) {
00315 
00316             $oCur = $this->getConfig()->getActShopCurrencyObject();
00317 
00318             $oDiscountPrice = oxNew( 'oxprice' );
00319             $oDiscountPrice->setBruttoPriceMode();
00320             $oDiscountPrice->setPrice( $this->oxdiscount__oxaddsum->value * $oCur->rate, $oPrice->getVat() );
00321         } else {
00322 
00323             $oDiscountPrice = oxNew( 'oxprice' );
00324             $oDiscountPrice->setBruttoPriceMode();
00325             $oDiscountPrice->setPrice( $oPrice->getBruttoPrice() / 100 * $this->oxdiscount__oxaddsum->value, $oPrice->getVat() );
00326         }
00327 
00328         $oDiscountPrice->multiply( $dAmount * -1 );
00329         $oPrice->addPrice( $oDiscountPrice );
00330     }
00331 
00339     public function getBundleAmount( $dAmount )
00340     {
00341         $dItemAmount = $this->oxdiscount__oxitmamount->value;
00342 
00343         // Multiplying bundled articles count, if allowed
00344         if ( $this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0 ) {
00345             $dItemAmount = floor( $dAmount / $this->oxdiscount__oxamount->value ) * $this->oxdiscount__oxitmamount->value;
00346         }
00347 
00348         return $dItemAmount;
00349     }
00350 
00358     protected function _checkForArticleCategories( $oArticle )
00359     {
00360         // check if article is in some assigned category
00361         $aCatIds = $oArticle->getCategoryIds();
00362         if (!$aCatIds || !count($aCatIds)) {
00363             // no categories are set for article, so no discounts from categories..
00364             return false;
00365         }
00366 
00367         $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
00368 
00369         $oDb = oxDb::getDb();
00370         // getOne appends limit 1, so this one should be fast enough
00371         $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = ".$oDb->quote($this->oxdiscount__oxid->value)." and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00372 
00373         return $oDb->getOne( $sQ );
00374     }
00375 
00381     public function getSimpleDiscount()
00382     {
00383         $oDiscount = new OxStdClass();
00384         $oDiscount->sOXID     = $this->getId();
00385         $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
00386         $oDiscount->sType     = $this->oxdiscount__oxaddsumtype->value;
00387 
00388         return $oDiscount;
00389     }
00390 
00391 }