OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxdiscount.php
Go to the documentation of this file.
1 <?php
2 
7 class oxDiscount extends oxI18n
8 {
14  protected $_sClassName = 'oxdiscount';
15 
21  protected $_dAmount = null;
22 
28  protected $_sBasketIdent = null;
29 
36 
42  protected $_aHasArticleDiscounts = array();
43 
47  public function __construct()
48  {
50  $this->init( 'oxdiscount' );
51  }
52 
60  public function delete( $sOXID = null )
61  {
62  if ( !$sOXID ) {
63  $sOXID = $this->getId();
64  }
65  if ( !$sOXID ) {
66  return false;
67  }
68 
69 
70  $oDb = oxDb::getDb();
71  $oDb->execute( 'delete from oxobject2discount where oxobject2discount.oxdiscountid = '.$oDb->quote($sOXID) );
72 
73  return parent::delete( $sOXID );
74  }
75 
83  public function isForArticle( $oArticle )
84  {
85 
86  // item discounts may only be applied for basket
87  if ( $this->oxdiscount__oxaddsumtype->value == 'itm' ) {
88  return false;
89  }
90 
91  if ( $this->oxdiscount__oxamount->value || $this->oxdiscount__oxprice->value ) {
92  return false;
93  }
94 
95  if ( $this->oxdiscount__oxpriceto->value && ($this->oxdiscount__oxpriceto->value < $oArticle->getBasePrice()) ) {
96  return false;
97  }
98 
99  $oDb = oxDb::getDb();
100 
101  $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
102 
103  //check for global discount (no articles, no categories)
104  if ( $this->_blIsForArticleOrForCategory ) {
105  return true;
106  } elseif ( $this->_blIsForArticleOrForCategory === null ) {
107 
108  $this->_blIsForArticleOrForCategory = false;
109  $sQ = "select 1 from oxobject2discount where oxdiscountid = $sDiscountIdQuoted and ( oxtype = 'oxarticles' or oxtype = 'oxcategories')";
110  if ( ! $oDb->getOne( $sQ ) ) {
111  $this->_blIsForArticleOrForCategory = true;
112  return true;
113  }
114  }
115 
116  $sArticleId = $oArticle->getProductId();
117 
118  if ( !$this->_blIsForArticleAndForCategory && !isset($this->_aHasArticleDiscounts[ $sArticleId ] ) ) {
119 
120  $this->_aHasArticleDiscounts[ $sArticleId ] = false ;
121 
122  // check if this article is assigned
123  $sQ = "select 1 from oxobject2discount where oxdiscountid = {$sDiscountIdQuoted} and oxtype = 'oxarticles' ";
124  $sQ .= $this->_getProductCheckQuery( $oArticle );
125 
126  if ( $oDb->getOne( $sQ ) ) {
127  $this->_aHasArticleDiscounts[ $sArticleId ] = true;
128  return true;
129  } else {
130  // check if article is in some assigned category
131  $aCatIds = $oArticle->getCategoryIds();
132  if (!$aCatIds || !count($aCatIds)) {
133  // no categories are set for article, so no discounts from categories..
134  return false;
135  }
136  $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
137  // getOne appends limit 1, so this one should be fast enough
138  $sQ = "select 1 from oxobject2discount where oxdiscountid = {$sDiscountIdQuoted} and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
139  if ( $oDb->getOne( $sQ ) ) {
140  $this->_aHasArticleDiscounts[ $sArticleId ] = true;
141  return true;
142  }
143  }
144  }
145 
146  return $this->_aHasArticleDiscounts[ $sArticleId ];
147  }
148 
156  public function isForBasketItem( $oArticle )
157  {
158  if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
159  return false;
160  }
161 
162  // skipping bundle discounts
163  if ( $this->oxdiscount__oxaddsumtype->value == 'itm' ) {
164  return false;
165  }
166 
167  $oDb = oxDb::getDb();
168 
169  // check if this article is assigned
170  $sQ = "select 1 from oxobject2discount where oxdiscountid = ".$oDb->quote( $this->oxdiscount__oxid->value)." and oxtype = 'oxarticles' ";
171  $sQ .= $this->_getProductCheckQuery( $oArticle );
172  if ( !( $blOk = ( bool ) $oDb->getOne( $sQ ) ) ) {
173 
174  // checking article category
175  $blOk = $this->_checkForArticleCategories( $oArticle );
176  }
177 
178  return $blOk;
179  }
180 
188  public function isForBasketAmount( $oBasket )
189  {
190  $dAmount = 0;
191  $aBasketItems = $oBasket->getContents();
192  foreach ( $aBasketItems as $oBasketItem ) {
193 
194  $oBasketArticle = $oBasketItem->getArticle(false);
195 
196  $blForBasketItem = false;
197  if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
198  $blForBasketItem = $this->isForBasketItem( $oBasketArticle );
199  } else {
200  $blForBasketItem = $this->isForBundleItem( $oBasketArticle );
201  }
202 
203  if ( $blForBasketItem ) {
204  $dRate = $oBasket->getBasketCurrency()->rate;
205  if ( $this->oxdiscount__oxprice->value ) {
206  if ( ( $oPrice = $oBasketArticle->getPrice() ) ) {
207  $dAmount += ($oPrice->getPrice() * $oBasketItem->getAmount())/$dRate;
208  }
209  } elseif ( $this->oxdiscount__oxamount->value ) {
210  $dAmount += $oBasketItem->getAmount();
211  }
212  }
213  }
214 
215  return $this->isForAmount( $dAmount );
216  }
217 
225  public function isForAmount( $dAmount )
226  {
227  $blIs = true;
228 
229  if ( $this->oxdiscount__oxprice->value &&
230  ( $dAmount < $this->oxdiscount__oxprice->value || $dAmount > $this->oxdiscount__oxpriceto->value ) ) {
231  $blIs = false;
232  } elseif ( $this->oxdiscount__oxamount->value &&
233  ( $dAmount < $this->oxdiscount__oxamount->value || $dAmount > $this->oxdiscount__oxamountto->value ) ) {
234  $blIs = false;
235  }
236 
237  return $blIs;
238  }
239 
247  public function isForBasket( $oBasket )
248  {
249  // initial configuration check
250  if ( $this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0 ) {
251  return false;
252  }
253 
254  $oSummary = $oBasket->getBasketSummary();
255  // amounts check
256  if ( $this->oxdiscount__oxamount->value && ( $oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value ) ) {
257  return false;
258  // price check
259  } elseif ($this->oxdiscount__oxprice->value) {
260  $dRate = $oBasket->getBasketCurrency()->rate;
261  if ( $oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value*$dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value*$dRate ) {
262  return false;
263  }
264  }
265 
266  // oxobject2discount configuration check
267  $oDb = oxDb::getDb();
268  $sQ = 'select 1 from oxobject2discount where oxdiscountid = ' . $oDb->quote($this->oxdiscount__oxid->value).' and oxtype in ("oxarticles", "oxcategories" ) ';
269 
270  return !( (bool) $oDb->getOne( $sQ ) );
271  }
272 
280  public function isForBundleItem( $oArticle )
281  {
282  if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
283  return false;
284  }
285 
286  $oDb = oxDb::getDb();
287  $sQ = "select 1 from oxobject2discount where oxdiscountid=".$oDb->quote( $this->getId() );
288  $sQ .= $this->_getProductCheckQuery( $oArticle );
289  if ( !( $blOk = (bool) $oDb->getOne( $sQ ) ) ) {
290  // additional checks for amounts and other dependencies
291  $blOk = $this->_checkForArticleCategories( $oArticle );
292  }
293  return $blOk;
294  }
295 
303  public function isForBundleBasket( $oBasket )
304  {
305  if ( $this->oxdiscount__oxaddsumtype->value != 'itm' ) {
306  return false;
307  }
308 
309  return $this->isForBasket( $oBasket );
310  }
311 
320  public function getAbsValue( $dPrice, $dAmount = 1 )
321  {
322  if ( $this->oxdiscount__oxaddsumtype->value == '%' ) {
323  return $dPrice * ( $this->oxdiscount__oxaddsum->value / 100 );
324  } else {
325  $oCur = $this->getConfig()->getActShopCurrencyObject();
326  return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
327  }
328  }
329 
340  public function applyDiscount( $oPrice, $dAmount = 1 )
341  {
342  if ( $this->oxdiscount__oxaddsumtype->value == 'abs' ) {
343  $oCur = $this->getConfig()->getActShopCurrencyObject();
344  $oPrice->subtract( $this->oxdiscount__oxaddsum->value * $oCur->rate );
345  } else {
346  $oPrice->multiply( (100 - $this->oxdiscount__oxaddsum->value) / 100 );
347  }
348 
349  if ( $oPrice->getBruttoPrice() < 0 || $oPrice->getNettoPrice() < 0 ) {
350  $oPrice->setPrice(0);
351  }
352  }
353 
361  public function getPercentage( $dPrice )
362  {
363  if ( $this->getAddSumType() == 'abs' && $dPrice > 0 ) {
364  return $this->getAddSum() / $dPrice * 100;
365  } else {
366  return $this->getAddSum();
367  }
368  }
369 
370 
371 
378  public function getAddSum()
379  {
380  if ( $this->oxdiscount__oxaddsumtype->value == 'abs' ) {
381  $oCur = $this->getConfig()->getActShopCurrencyObject();
382  return $this->oxdiscount__oxaddsum->value * $oCur->rate;
383  } else {
384  return $this->oxdiscount__oxaddsum->value;
385  }
386  }
387 
393  public function getAddSumType()
394  {
395  return $this->oxdiscount__oxaddsumtype->value;
396  }
397 
398 
399 
400 
408  public function getBundleAmount( $dAmount )
409  {
410  $dItemAmount = $this->oxdiscount__oxitmamount->value;
411 
412  // Multiplying bundled articles count, if allowed
413  if ( $this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0 ) {
414  $dItemAmount = floor( $dAmount / $this->oxdiscount__oxamount->value ) * $this->oxdiscount__oxitmamount->value;
415  }
416 
417  return $dItemAmount;
418  }
419 
427  protected function _checkForArticleCategories( $oArticle )
428  {
429  // check if article is in some assigned category
430  $aCatIds = $oArticle->getCategoryIds();
431  if (!$aCatIds || !count($aCatIds)) {
432  // no categories are set for article, so no discounts from categories..
433  return false;
434  }
435 
436  $sCatIds = "(".implode(",", oxDb::getInstance()->quoteArray($aCatIds)).")";
437 
438  $oDb = oxDb::getDb();
439  // getOne appends limit 1, so this one should be fast enough
440  $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = ".$oDb->quote($this->oxdiscount__oxid->value)." and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
441 
442  return $oDb->getOne( $sQ );
443  }
444 
450  public function getSimpleDiscount()
451  {
452  $oDiscount = new stdClass();
453  $oDiscount->sOXID = $this->getId();
454  $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
455  $oDiscount->sType = $this->oxdiscount__oxaddsumtype->value;
456 
457  return $oDiscount;
458  }
459 
465  public function getArticleIds()
466  {
467  return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '".$this->getId()."' and oxtype = 'oxarticles'");
468  }
469 
475  public function getCategoryIds()
476  {
477  return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '".$this->getId()."' and oxtype = 'oxcategories'");
478  }
479 
488  protected function _getProductCheckQuery( $oProduct )
489  {
490  $oDb = oxDb::getDb();
491  // check if this article is assigned
492  if ( ( $sParentId = $oProduct->getProductParentId() ) ) {
493  $sArticleId = " and ( oxobjectid = ".$oDb->quote( $oProduct->getProductId() )." or oxobjectid = ".$oDb->quote( $sParentId ) . " )";
494  } else {
495  $sArticleId = " and oxobjectid = ".$oDb->quote( $oProduct->getProductId() );
496  }
497 
498  return $sArticleId;
499  }
500 
501 
502 }