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 = '{$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         $sQ  = "select 1 from oxobject2discount where oxdiscountid='".$this->getId()."' ";
00250         $sQ .= $this->_getProductCheckQuery( $oArticle );
00251         if ( !( $blOk = (bool) oxDb::getDb()->getOne( $sQ ) ) ) {
00252             // additional checks for amounts and other dependencies
00253             $blOk = $this->_checkForArticleCategories( $oArticle );
00254         }
00255         return $blOk;
00256     }
00257 
00265     public function isForBundleBasket( $oBasket )
00266     {
00267         if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
00268             return false;
00269         }
00270 
00271         return $this->isForBasket( $oBasket );
00272     }
00273 
00282     public function getAbsValue( $dPrice, $dAmount = 1 )
00283     {
00284         if ( $this->oxdiscount__oxaddsumtype->value == '%' ) {
00285             return $dPrice * ( $this->oxdiscount__oxaddsum->value / 100 );
00286         } else {
00287             $oCur = $this->getConfig()->getActShopCurrencyObject();
00288             return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
00289         }
00290     }
00291 
00300     public function applyDiscount( $oPrice, $dAmount = 1 )
00301     {
00302         if ( $this->oxdiscount__oxaddsumtype->value == 'abs' ) {
00303 
00304             $oCur = $this->getConfig()->getActShopCurrencyObject();
00305 
00306             $oDiscountPrice = oxNew( 'oxprice' );
00307             $oDiscountPrice->setBruttoPriceMode();
00308             $oDiscountPrice->setPrice( $this->oxdiscount__oxaddsum->value * $oCur->rate, $oPrice->getVat() );
00309         } else {
00310 
00311             $oDiscountPrice = oxNew( 'oxprice' );
00312             $oDiscountPrice->setBruttoPriceMode();
00313             $oDiscountPrice->setPrice( $oPrice->getBruttoPrice() / 100 * $this->oxdiscount__oxaddsum->value, $oPrice->getVat() );
00314         }
00315 
00316         $oDiscountPrice->multiply( $dAmount * -1 );
00317         $oPrice->addPrice( $oDiscountPrice );
00318     }
00319 
00327     public function getBundleAmount( $dAmount )
00328     {
00329         $dItemAmount = $this->oxdiscount__oxitmamount->value;
00330 
00331         // Multiplying bundled articles count, if allowed
00332         if ( $this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0 ) {
00333             $dItemAmount = floor( $dAmount / $this->oxdiscount__oxamount->value ) * $this->oxdiscount__oxitmamount->value;
00334         }
00335 
00336         return $dItemAmount;
00337     }
00338 
00346     protected function _checkForArticleCategories( $oArticle )
00347     {
00348         // check if article is in some assigned category
00349         $aCatIds = $oArticle->getCategoryIds();
00350         if (!$aCatIds || !count($aCatIds)) {
00351             // no categories are set for article, so no discounts from categories..
00352             return false;
00353         }
00354 
00355         $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
00356 
00357         $oDb = oxDb::getDb();
00358         // getOne appends limit 1, so this one should be fast enough
00359         $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = ".$oDb->quote($this->oxdiscount__oxid->value)." and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
00360 
00361         return $oDb->getOne( $sQ );
00362     }
00363 
00369     public function getSimpleDiscount()
00370     {
00371         $oDiscount = new OxStdClass();
00372         $oDiscount->sOXID     = $this->getId();
00373         $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
00374         $oDiscount->sType     = $this->oxdiscount__oxaddsumtype->value;
00375 
00376         return $oDiscount;
00377     }
00378 
00387     protected function _getProductCheckQuery( $oProduct )
00388     {
00389         // check if this article is assigned
00390         if ( ( $sParentId = $oProduct->getProductParentId() ) ) {
00391             $sArticleId = " and ( oxobjectid = '".$oProduct->getProductId()."' or oxobjectid = '{$sParentId}' )";
00392         } else {
00393             $sArticleId = " and oxobjectid = '".$oProduct->getProductId()."'";
00394         }
00395 
00396         return $sArticleId;
00397     }
00398 
00399 }