OXID eShop CE  4.9.6
 All Classes Files Functions Variables Pages
oxdiscount.php
Go to the documentation of this file.
1 <?php
2 
7 class oxDiscount extends oxI18n
8 {
9 
15  protected $_sClassName = 'oxdiscount';
16 
22  protected $_dAmount = null;
23 
29  protected $_sBasketIdent = null;
30 
37 
43  protected $_aHasArticleDiscounts = array();
44 
48  public function __construct()
49  {
51  $this->init('oxdiscount');
52  }
53 
61  public function delete($sOXID = null)
62  {
63  if (!$sOXID) {
64  $sOXID = $this->getId();
65  }
66  if (!$sOXID) {
67  return false;
68  }
69 
70 
71  $oDb = oxDb::getDb();
72  $oDb->execute('delete from oxobject2discount where oxobject2discount.oxdiscountid = ' . $oDb->quote($sOXID));
73 
74  return parent::delete($sOXID);
75  }
76 
82  public function isGlobalDiscount()
83  {
84  if (is_null($this->_blIsForArticleOrForCategory)) {
85  $oDb = oxDb::getDb();
86  $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
87 
88  $sQuery = "select 1
89  from oxobject2discount
90  where oxdiscountid = $sDiscountIdQuoted and (oxtype = 'oxarticles' or oxtype = 'oxcategories')";
91 
92  $this->_blIsForArticleOrForCategory = $oDb->getOne($sQuery) ? false : true;
93  }
94 
96  }
97 
105  public function isForArticle($oArticle)
106  {
107  // item discounts may only be applied for basket
108  if ($this->oxdiscount__oxaddsumtype->value == 'itm') {
109  return false;
110  }
111 
112  if ($this->oxdiscount__oxamount->value || $this->oxdiscount__oxprice->value) {
113  return false;
114  }
115 
116  if ($this->oxdiscount__oxpriceto->value && ($this->oxdiscount__oxpriceto->value < $oArticle->getBasePrice())) {
117  return false;
118  }
119 
120  if ($this->isGlobalDiscount()) {
121  return true;
122  }
123 
124  $sArticleId = $oArticle->getProductId();
125 
126  if (!isset($this->_aHasArticleDiscounts[$sArticleId])) {
127 
128  $blResult = $this->_isArticleAssigned($oArticle) || $this->_isCategoriesAssigned($oArticle->getCategoryIds());
129 
130  $this->_aHasArticleDiscounts[$sArticleId] = $blResult;
131  }
132 
133  return $this->_aHasArticleDiscounts[$sArticleId];
134  }
135 
143  public function isForBasketItem($oArticle)
144  {
145  if ($this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0) {
146  return false;
147  }
148 
149  // skipping bundle discounts
150  if ($this->oxdiscount__oxaddsumtype->value == 'itm') {
151  return false;
152  }
153 
154  $oDb = oxDb::getDb();
155 
156  // check if this article is assigned
157  $sQ = "select 1 from oxobject2discount where oxdiscountid = " . $oDb->quote($this->oxdiscount__oxid->value) . " and oxtype = 'oxarticles' ";
158  $sQ .= $this->_getProductCheckQuery($oArticle);
159  if (!($blOk = ( bool ) $oDb->getOne($sQ))) {
160 
161  // checking article category
162  $blOk = $this->_checkForArticleCategories($oArticle);
163  }
164 
165  return $blOk;
166  }
167 
175  public function isForBasketAmount($oBasket)
176  {
177  $dAmount = 0;
178  $aBasketItems = $oBasket->getContents();
179  foreach ($aBasketItems as $oBasketItem) {
180 
181  $oBasketArticle = $oBasketItem->getArticle(false);
182 
183  $blForBasketItem = false;
184  if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
185  $blForBasketItem = $this->isForBasketItem($oBasketArticle);
186  } else {
187  $blForBasketItem = $this->isForBundleItem($oBasketArticle);
188  }
189 
190  if ($blForBasketItem) {
191  $dRate = $oBasket->getBasketCurrency()->rate;
192  if ($this->oxdiscount__oxprice->value) {
193  if (($oPrice = $oBasketArticle->getPrice())) {
194  $dAmount += ($oPrice->getPrice() * $oBasketItem->getAmount()) / $dRate;
195  }
196  } elseif ($this->oxdiscount__oxamount->value) {
197  $dAmount += $oBasketItem->getAmount();
198  }
199  }
200  }
201 
202  return $this->isForAmount($dAmount);
203  }
204 
212  public function isForAmount($dAmount)
213  {
214  $blIs = true;
215 
216  if ($this->oxdiscount__oxprice->value &&
217  ($dAmount < $this->oxdiscount__oxprice->value || $dAmount > $this->oxdiscount__oxpriceto->value)
218  ) {
219  $blIs = false;
220  } elseif ($this->oxdiscount__oxamount->value &&
221  ($dAmount < $this->oxdiscount__oxamount->value || $dAmount > $this->oxdiscount__oxamountto->value)
222  ) {
223  $blIs = false;
224  }
225 
226  return $blIs;
227  }
228 
236  public function isForBasket($oBasket)
237  {
238  // initial configuration check
239  if ($this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0) {
240  return false;
241  }
242 
243  $oSummary = $oBasket->getBasketSummary();
244  // amounts check
245  if ($this->oxdiscount__oxamount->value && ($oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value)) {
246  return false;
247  // price check
248  } elseif ($this->oxdiscount__oxprice->value) {
249  $dRate = $oBasket->getBasketCurrency()->rate;
250  if ($oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value * $dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value * $dRate) {
251  return false;
252  }
253  }
254 
255  // oxobject2discount configuration check
256  $oDb = oxDb::getDb();
257  $sQ = 'select 1 from oxobject2discount where oxdiscountid = ' . $oDb->quote($this->oxdiscount__oxid->value) . ' and oxtype in ("oxarticles", "oxcategories" ) ';
258 
259  return !((bool) $oDb->getOne($sQ));
260  }
261 
269  public function isForBundleItem($oArticle)
270  {
271  if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
272  return false;
273  }
274 
275  $oDb = oxDb::getDb();
276  $sQ = "select 1 from oxobject2discount where oxdiscountid=" . $oDb->quote($this->getId());
277  $sQ .= $this->_getProductCheckQuery($oArticle);
278  if (!($blOk = (bool) $oDb->getOne($sQ))) {
279  // additional checks for amounts and other dependencies
280  $blOk = $this->_checkForArticleCategories($oArticle);
281  }
282 
283  return $blOk;
284  }
285 
293  public function isForBundleBasket($oBasket)
294  {
295  if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
296  return false;
297  }
298 
299  return $this->isForBasket($oBasket);
300  }
301 
310  public function getAbsValue($dPrice, $dAmount = 1)
311  {
312  if ($this->oxdiscount__oxaddsumtype->value == '%') {
313  return $dPrice * ($this->oxdiscount__oxaddsum->value / 100);
314  } else {
315  $oCur = $this->getConfig()->getActShopCurrencyObject();
316 
317  return $this->oxdiscount__oxaddsum->value * $dAmount * $oCur->rate;
318  }
319  }
320 
328  public function getPercentage($dPrice)
329  {
330  if ($this->getAddSumType() == 'abs' && $dPrice > 0) {
331  return $this->getAddSum() / $dPrice * 100;
332  } else {
333  return $this->getAddSum();
334  }
335  }
336 
343  public function getAddSum()
344  {
345  if ($this->oxdiscount__oxaddsumtype->value == 'abs') {
346  $oCur = $this->getConfig()->getActShopCurrencyObject();
347 
348  return $this->oxdiscount__oxaddsum->value * $oCur->rate;
349  } else {
350  return $this->oxdiscount__oxaddsum->value;
351  }
352  }
353 
359  public function getAddSumType()
360  {
361  return $this->oxdiscount__oxaddsumtype->value;
362  }
363 
371  public function getBundleAmount($dAmount)
372  {
373  $dItemAmount = $this->oxdiscount__oxitmamount->value;
374 
375  // Multiplying bundled articles count, if allowed
376  if ($this->oxdiscount__oxitmmultiple->value && $this->oxdiscount__oxamount->value > 0) {
377  $dItemAmount = floor($dAmount / $this->oxdiscount__oxamount->value) * $this->oxdiscount__oxitmamount->value;
378  }
379 
380  return $dItemAmount;
381  }
382 
388  public function getSimpleDiscount()
389  {
390  $oDiscount = new stdClass();
391  $oDiscount->sOXID = $this->getId();
392  $oDiscount->sDiscount = $this->oxdiscount__oxtitle->value;
393  $oDiscount->sType = $this->oxdiscount__oxaddsumtype->value;
394 
395  return $oDiscount;
396  }
397 
403  public function getArticleIds()
404  {
405  return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '" . $this->getId() . "' and oxtype = 'oxarticles'");
406  }
407 
413  public function getCategoryIds()
414  {
415  return oxDb::getDb()->getCol("select `oxobjectid` from oxobject2discount where oxdiscountid = '" . $this->getId() . "' and oxtype = 'oxcategories'");
416  }
417 
418 
426  protected function _checkForArticleCategories($oArticle)
427  {
428  // check if article is in some assigned category
429  $aCatIds = $oArticle->getCategoryIds();
430  if (!$aCatIds || !count($aCatIds)) {
431  // no categories are set for article, so no discounts from categories..
432  return false;
433  }
434 
435  $sCatIds = "(" . implode(",", oxDb::getInstance()->quoteArray($aCatIds)) . ")";
436 
437  $oDb = oxDb::getDb();
438  // getOne appends limit 1, so this one should be fast enough
439  $sQ = "select oxobjectid from oxobject2discount where oxdiscountid = " . $oDb->quote($this->oxdiscount__oxid->value) . " and oxobjectid in $sCatIds and oxtype = 'oxcategories'";
440 
441  return $oDb->getOne($sQ);
442  }
443 
452  protected function _getProductCheckQuery($oProduct)
453  {
454  $oDb = oxDb::getDb();
455  // check if this article is assigned
456  if (($sParentId = $oProduct->getParentId())) {
457  $sArticleId = " and ( oxobjectid = " . $oDb->quote($oProduct->getProductId()) . " or oxobjectid = " . $oDb->quote($sParentId) . " )";
458  } else {
459  $sArticleId = " and oxobjectid = " . $oDb->quote($oProduct->getProductId());
460  }
461 
462  return $sArticleId;
463  }
464 
472  protected function _isArticleAssigned($oArticle)
473  {
474  $oDb = oxDb::getDb();
475  $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
476 
477  $sQ = "select 1
478  from oxobject2discount
479  where oxdiscountid = {$sDiscountIdQuoted} and oxtype = 'oxarticles' ";
480  $sQ .= $this->_getProductCheckQuery($oArticle);
481 
482  return $oDb->getOne($sQ) ? true : false;
483  }
484 
492  protected function _isCategoriesAssigned($aCategoryIds)
493  {
494  if (empty($aCategoryIds)) {
495  return false;
496  }
497 
498  $oDb = oxDb::getDb();
499  $sDiscountIdQuoted = $oDb->quote($this->oxdiscount__oxid->value);
500 
501  $sCategoryIds = "(" . implode(",", oxDb::getInstance()->quoteArray($aCategoryIds)) . ")";
502  $sQ = "select 1
503  from oxobject2discount
504  where oxdiscountid = {$sDiscountIdQuoted} and oxobjectid in {$sCategoryIds} and oxtype = 'oxcategories'";
505 
506  return $oDb->getOne($sQ) ? true : false;
507  }
508 }