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         if ( !$myDB->getOne( $sQ ) ) {
00089             return true;
00090         }
00091 
00092         // check if this article is assigned
00093         $sQ  = "select 1 from oxobject2discount where oxdiscountid = {$sDiscountIdQuoted} and oxtype = 'oxarticles' ";
00094         $sQ .= $this->_getProductCheckQuery( $oArticle );
00095         if ( $myDB->getOne( $sQ ) ) {
00096             return true;
00097         } else {
00098             // check if article is in some assigned category
00099             $aCatIds = $oArticle->getCategoryIds();
00100             if (!$aCatIds || !count($aCatIds)) {
00101                 // no categories are set for article, so no discounts from categories..
00102                 return false;
00103             }
00104             $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
00105             // getOne appends limit 1, so this one should be fast enough
00106             $sQ = "select 1 from oxobject2discount where oxdiscountid = {$sDiscountIdQuoted} and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00107             if ( $myDB->getOne( $sQ ) ) {
00108                 return true;
00109             }
00110         }
00111         return false;
00112     }
00113 
00121     public function isForBasketItem( $oArticle )
00122     {
00123         if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
00124             return false;
00125         }
00126 
00127         // skipping bundle discounts
00128         if ( $this->oxdiscount__oxaddsumtype->value == 'itm' ) {
00129             return false;
00130         }
00131 
00132         $myDB = oxDb::getDb();
00133 
00134         // check if this article is assigned
00135         $sQ  = "select 1 from oxobject2discount where oxdiscountid = ".$myDB->quote( $this->oxdiscount__oxid->value)." and oxtype = 'oxarticles' ";
00136         $sQ .= $this->_getProductCheckQuery( $oArticle );
00137         if ( !( $blOk = ( bool ) $myDB->getOne( $sQ ) ) ) {
00138 
00139             // checkin article cateogry
00140             $blOk = $this->_checkForArticleCategories( $oArticle );
00141         }
00142 
00143         return $blOk;
00144     }
00145 
00153     public function isForBasketAmount( $oBasket )
00154     {
00155         $dAmount = 0;
00156         $aBasketItems = $oBasket->getContents();
00157         foreach ( $aBasketItems as $oBasketItem ) {
00158 
00159             $oBasketArticle = $oBasketItem->getArticle(false);
00160 
00161             $blForBasketItem = false;
00162             if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00163                 $blForBasketItem = $this->isForBasketItem( $oBasketArticle );
00164             } else {
00165                 $blForBasketItem = $this->isForBundleItem( $oBasketArticle );
00166             }
00167 
00168             if ( $blForBasketItem ) {
00169                 $dRate = $oBasket->getBasketCurrency()->rate;
00170                 if ( $this->oxdiscount__oxprice->value ) {
00171                     if ( ( $oPrice = $oBasketArticle->getPrice() ) ) {
00172                         $dAmount += ($oPrice->getBruttoPrice() * $oBasketItem->getAmount())/$dRate;
00173                     }
00174                 } elseif ( $this->oxdiscount__oxamount->value ) {
00175                     $dAmount += $oBasketItem->getAmount();
00176                 }
00177             }
00178         }
00179 
00180         return $this->isForAmount( $dAmount );
00181     }
00182 
00190     public function isForAmount( $dAmount )
00191     {
00192         $blIs = true;
00193 
00194         if ( $this->oxdiscount__oxprice->value &&
00195             ( $dAmount < $this->oxdiscount__oxprice->value || $dAmount > $this->oxdiscount__oxpriceto->value ) ) {
00196             $blIs = false;
00197         } elseif ( $this->oxdiscount__oxamount->value &&
00198             ( $dAmount < $this->oxdiscount__oxamount->value || $dAmount > $this->oxdiscount__oxamountto->value ) ) {
00199             $blIs = false;
00200         }
00201         return $blIs;
00202     }
00203 
00211     public function isForBasket( $oBasket )
00212     {
00213         // initial configuration check
00214         if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
00215             return false;
00216         }
00217 
00218         $oSummary = $oBasket->getBasketSummary();
00219         // amounts check
00220         if ( $this->oxdiscount__oxamount->value && ( $oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value ) ) {
00221             return false;
00222             // price check
00223         } elseif ($this->oxdiscount__oxprice->value) {
00224             $dRate = $oBasket->getBasketCurrency()->rate;
00225             if ( $oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value*$dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value*$dRate ) {
00226                 return false;
00227             }
00228         }
00229 
00230         // oxobject2discount configuration check
00231         $sQ = 'select 1 from oxobject2discount where oxdiscountid = '.oxDb::getDb()->quote($this->oxdiscount__oxid->value).' and oxtype in ("oxarticles", "oxcategories" ) ';
00232 
00233         return !( (bool) oxDb::getDb()->getOne( $sQ ) );
00234     }
00235 
00243     public function isForBundleItem( $oArticle )
00244     {
00245         if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00246             return false;
00247         }
00248 
00249         $oDb = oxDb::getDb();
00250         $sQ  = "select 1 from oxobject2discount where oxdiscountid=".$oDb->quote( $this->getId() );
00251         $sQ .= $this->_getProductCheckQuery( $oArticle );
00252         if ( !( $blOk = (bool) $oDb->getOne( $sQ ) ) ) {
00253             // additional checks for amounts and other dependencies
00254             $blOk = $this->_checkForArticleCategories( $oArticle );
00255         }
00256         return $blOk;
00257     }
00258 
00266     public function isForBundleBasket( $oBasket )
00267     {
00268         if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00269             return false;
00270         }
00271 
00272         return $this->isForBasket( $oBasket );
00273     }
00274 
00283     public function getAbsValue( $dPrice, $dAmount = 1 )
00284     {
00285         if ( $this->oxdiscount__oxaddsumtype->value == '%' ) {
00286             return $dPrice * ( $this->oxdiscount__oxaddsum->value / 100 );
00287         } else {
00288             $oCur = $this->getConfig()->getActShopCurrencyObject();
00289             return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
00290         }
00291     }
00292 
00301     public function applyDiscount( $oPrice, $dAmount = 1 )
00302     {
00303         if ( $this->oxdiscount__oxaddsumtype->value == 'abs' ) {
00304 
00305             $oCur = $this->getConfig()->getActShopCurrencyObject();
00306 
00307             $oDiscountPrice = oxNew( 'oxprice' );
00308             $oDiscountPrice->setBruttoPriceMode();
00309             $oDiscountPrice->setPrice( $this->oxdiscount__oxaddsum->value * $oCur->rate, $oPrice->getVat() );
00310         } else {
00311 
00312             $oDiscountPrice = oxNew( 'oxprice' );
00313             $oDiscountPrice->setBruttoPriceMode();
00314             $oDiscountPrice->setPrice( $oPrice->getBruttoPrice() / 100 * $this->oxdiscount__oxaddsum->value, $oPrice->getVat() );
00315         }
00316 
00317         $oDiscountPrice->multiply( $dAmount * -1 );
00318         $oPrice->addPrice( $oDiscountPrice );
00319     }
00320 
00328     public function getBundleAmount( $dAmount )
00329     {
00330         $dItemAmount = $this->oxdiscount__oxitmamount->value;
00331 
00332         // Multiplying bundled articles count, if allowed
00333         if ( $this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0 ) {
00334             $dItemAmount = floor( $dAmount / $this->oxdiscount__oxamount->value ) * $this->oxdiscount__oxitmamount->value;
00335         }
00336 
00337         return $dItemAmount;
00338     }
00339 
00347     protected function _checkForArticleCategories( $oArticle )
00348     {
00349         // check if article is in some assigned category
00350         $aCatIds = $oArticle->getCategoryIds();
00351         if (!$aCatIds || !count($aCatIds)) {
00352             // no categories are set for article, so no discounts from categories..
00353             return false;
00354         }
00355 
00356         $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
00357 
00358         $oDb = oxDb::getDb();
00359         // getOne appends limit 1, so this one should be fast enough
00360         $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = ".$oDb->quote($this->oxdiscount__oxid->value)." and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00361 
00362         return $oDb->getOne( $sQ );
00363     }
00364 
00370     public function getSimpleDiscount()
00371     {
00372         $oDiscount = new OxStdClass();
00373         $oDiscount->sOXID     = $this->getId();
00374         $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
00375         $oDiscount->sType     = $this->oxdiscount__oxaddsumtype->value;
00376 
00377         return $oDiscount;
00378     }
00379 
00388     protected function _getProductCheckQuery( $oProduct )
00389     {
00390         $oDb = oxDb::getDb();
00391         // check if this article is assigned
00392         if ( ( $sParentId = $oProduct->getProductParentId() ) ) {
00393             $sArticleId = " and ( oxobjectid = ".$oDb->quote( $oProduct->getProductId() )." or oxobjectid = ".$oDb->quote( $sParentId ) . " )";
00394         } else {
00395             $sArticleId = " and oxobjectid = ".$oDb->quote( $oProduct->getProductId() );
00396         }
00397 
00398         return $sArticleId;
00399     }
00400 
00401 }