Go to the documentation of this file.00001 <?php
00002
00008 class oxVoucher extends oxBase
00009 {
00010
00011 protected $_oSerie = null;
00012
00018 protected $_blDisableShopCheck = true;
00019
00023 protected $_sClassName = 'oxvoucher';
00024
00028 public function __construct()
00029 {
00030 parent::__construct();
00031 $this->init( 'oxvouchers' );
00032 }
00033
00045 public function getVoucherByNr( $sVoucherNr, $aVouchers = array(), $blCheckavalability = false )
00046 {
00047 $oRet = null;
00048 if ( !is_null( $sVoucherNr ) ) {
00049
00050 $sViewName = $this->getViewName();
00051 $sSeriesViewName = getViewName( 'oxvoucherseries' );
00052 $myDB = oxDb::getDb();
00053
00054 $sQ = "select {$sViewName}.* from {$sViewName}, {$sSeriesViewName} where
00055 {$sSeriesViewName}.oxid = {$sViewName}.oxvoucherserieid and
00056 {$sViewName}.oxvouchernr = " . $myDB->quote( $sVoucherNr ) . " and ";
00057
00058 if ( is_array( $aVouchers ) ) {
00059 foreach ( $aVouchers as $sVoucherId => $sSkipVoucherNr ) {
00060 $sQ .= "{$sViewName}.oxid != " . $myDB->quote( $sVoucherId ) . " and ";
00061 }
00062 }
00063 $sQ .= "( {$sViewName}.oxorderid is NULL || {$sViewName}.oxorderid = '' ) ";
00064
00065
00066 if ( $blCheckavalability ) {
00067 $iTime = time() - 3600 * 3;
00068 $sQ .= " and {$sViewName}.oxreserved < '{$iTime}' ";
00069 }
00070
00071 $sQ .= " limit 1";
00072
00073 if ( ! ( $oRet = $this->assignRecord( $sQ ) ) ) {
00074 $oEx = oxNew( 'oxVoucherException' );
00075 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOVOUCHER' );
00076 $oEx->setVoucherNr( $sVoucherNr );
00077 throw $oEx;
00078 }
00079 }
00080
00081 return $oRet;
00082 }
00083
00093 public function markAsUsed( $sOrderId, $sUserId, $dDiscount )
00094 {
00095
00096 if ( $this->oxvouchers__oxid->value ) {
00097 $this->oxvouchers__oxorderid->setValue($sOrderId);
00098 $this->oxvouchers__oxuserid->setValue($sUserId);
00099 $this->oxvouchers__oxdiscount->setValue($dDiscount);
00100 $this->oxvouchers__oxdateused->setValue(date( "Y-m-d", oxUtilsDate::getInstance()->getTime() ));
00101 $this->save();
00102 }
00103 }
00104
00110 public function markAsReserved()
00111 {
00112
00113 $sVoucherID = $this->oxvouchers__oxid->value;
00114
00115 if ( $sVoucherID ) {
00116 $myDB = oxDb::getDb();
00117 $sQ = "update oxvouchers set oxreserved = " . time() . " where oxid = " . $myDB->quote( $sVoucherID );
00118 $myDB->Execute( $sQ );
00119 }
00120 }
00121
00127 public function unMarkAsReserved()
00128 {
00129
00130 $sVoucherID = $this->oxvouchers__oxid->value;
00131
00132 if ( $sVoucherID ) {
00133 $myDB = oxDb::getDb();
00134 $sQ = "update oxvouchers set oxreserved = 0 where oxid = " . $myDB->quote( $sVoucherID );
00135 $myDB->Execute($sQ);
00136 }
00137 }
00138
00148 public function getDiscountValue( $dPrice )
00149 {
00150 if ($this->_isProductVoucher()) {
00151 return $this->_getProductDiscoutValue( $dPrice );
00152 } elseif ($this->_isCategoryVoucher()) {
00153 return $this->_getCategoryDiscoutValue( $dPrice );
00154 } else {
00155 return $this->_getGenericDiscoutValue( $dPrice );
00156 }
00157 }
00158
00159
00170 public function checkVoucherAvailability( $aVouchers, $dPrice )
00171 {
00172 $this->_isAvailableWithSameSeries( $aVouchers );
00173 $this->_isAvailableWithOtherSeries( $aVouchers );
00174 $this->_isValidDate();
00175 $this->_isAvailablePrice( $dPrice );
00176 $this->_isNotReserved();
00177
00178
00179 return true;
00180 }
00181
00193 public function checkBasketVoucherAvailability( $aVouchers, $dPrice )
00194 {
00195 $this->_isAvailableWithSameSeries( $aVouchers );
00196 $this->_isAvailableWithOtherSeries( $aVouchers );
00197 $this->_isValidDate();
00198 $this->_isAvailablePrice( $dPrice );
00199
00200
00201 return true;
00202 }
00203
00213 protected function _isAvailablePrice( $dPrice )
00214 {
00215 if ( $this->getDiscountValue( $dPrice ) < 0 ) {
00216 $oEx = oxNew( 'oxVoucherException' );
00217 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00218 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00219 throw $oEx;
00220 }
00221 $oSerie = $this->getSerie();
00222 $oCur = $this->getConfig()->getActShopCurrencyObject();
00223 if ( $oSerie->oxvoucherseries__oxminimumvalue->value && $dPrice < ($oSerie->oxvoucherseries__oxminimumvalue->value*$oCur->rate) ) {
00224 $oEx = oxNew( 'oxVoucherException' );
00225 $oEx->setMessage('EXCEPTION_VOUCHER_INCORRECTPRICE');
00226 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00227 throw $oEx;
00228 }
00229
00230 return true;
00231 }
00232
00244 protected function _isAvailableWithSameSeries( $aVouchers )
00245 {
00246 if ( is_array( $aVouchers ) ) {
00247 $sId = $this->getId();
00248 if (isset($aVouchers[$sId])) {
00249 unset($aVouchers[$sId]);
00250 }
00251 $oSerie = $this->getSerie();
00252 if (!$oSerie->oxvoucherseries__oxallowsameseries->value) {
00253 foreach ( $aVouchers as $voucherId => $voucherNr ) {
00254 $oVoucher = oxNew( 'oxvoucher' );
00255 $oVoucher->load($voucherId);
00256 if ( $this->oxvouchers__oxvoucherserieid->value == $oVoucher->oxvouchers__oxvoucherserieid->value ) {
00257 $oEx = oxNew( 'oxVoucherException' );
00258 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDSAMESERIES');
00259 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00260 throw $oEx;
00261 }
00262 }
00263 }
00264 }
00265
00266 return true;
00267 }
00268
00279 protected function _isAvailableWithOtherSeries( $aVouchers )
00280 {
00281 if ( is_array( $aVouchers ) && count($aVouchers) ) {
00282 $oSerie = $this->getSerie();
00283 $sIds = implode(',', oxDb::getInstance()->quoteArray( array_keys( $aVouchers ) ) );
00284 $blAvailable = true;
00285 $myDB = oxDb::getDb();
00286 if (!$oSerie->oxvoucherseries__oxallowotherseries->value) {
00287
00288 $sSql = "select 1 from oxvouchers where oxvouchers.oxid in ($sIds) and ";
00289 $sSql .= "oxvouchers.oxvoucherserieid != " . $myDB->quote( $this->oxvouchers__oxvoucherserieid->value ) ;
00290 $blAvailable &= !$myDB->getOne($sSql);
00291 } else {
00292
00293 $sSql = "select 1 from oxvouchers left join oxvoucherseries on oxvouchers.oxvoucherserieid=oxvoucherseries.oxid ";
00294 $sSql .= "where oxvouchers.oxid in ($sIds) and oxvouchers.oxvoucherserieid != " . $myDB->quote( $this->oxvouchers__oxvoucherserieid->value );
00295 $sSql .= "and not oxvoucherseries.oxallowotherseries";
00296 $blAvailable &= !$myDB->getOne($sSql);
00297 }
00298 if ( !$blAvailable ) {
00299 $oEx = oxNew( 'oxVoucherException' );
00300 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDOTHERSERIES');
00301 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00302 throw $oEx;
00303 }
00304 }
00305
00306 return true;
00307 }
00308
00316 protected function _isValidDate()
00317 {
00318 $oSerie = $this->getSerie();
00319
00320 $sDefTimeStamp = oxUtilsDate::getInstance()->formatDBDate( '-' );
00321 if ( $oSerie->oxvoucherseries__oxbegindate->value == $sDefTimeStamp &&
00322 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00323 return true;
00324 }
00325
00326 if ( ( strtotime( $oSerie->oxvoucherseries__oxbegindate->value ) < time() &&
00327 strtotime( $oSerie->oxvoucherseries__oxenddate->value ) > time() ) ||
00328 !$oSerie->oxvoucherseries__oxenddate->value ||
00329 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00330 return true;
00331 }
00332
00333 $oEx = oxNew( 'oxVoucherException' );
00334 $oEx->setMessage('EXCEPTION_VOUCHER_ISNOTVALIDDATE');
00335 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00336 throw $oEx;
00337 }
00338
00346 protected function _isNotReserved()
00347 {
00348
00349 if ( $this->oxvouchers__oxreserved->value < time() - 3600 * 3 ) {
00350 return true;
00351 }
00352
00353 $oEx = oxNew( 'oxVoucherException' );
00354 $oEx->setMessage('EXCEPTION_VOUCHER_ISRESERVED');
00355 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00356 throw $oEx;
00357 }
00358
00359
00369 public function checkUserAvailability( $oUser )
00370 {
00371
00372 $this->_isAvailableInOtherOrder( $oUser );
00373 $this->_isValidUserGroup( $oUser );
00374
00375
00376 return true;
00377 }
00378
00388 protected function _isAvailableInOtherOrder( $oUser )
00389 {
00390 $oSerie = $this->getSerie();
00391 if ( !$oSerie->oxvoucherseries__oxallowuseanother->value ) {
00392
00393 $myDB = oxDb::getDb();
00394 $sSelect = 'select count(*) from '.$this->getViewName().' where oxuserid = '. $myDB->quote( $oUser->oxuser__oxid->value ) . ' and ';
00395 $sSelect .= 'oxvoucherserieid = ' . $myDB->quote( $this->oxvouchers__oxvoucherserieid->value ) . ' and ';
00396 $sSelect .= 'oxorderid is not NULL and oxorderid != "" ';
00397
00398 if ( $myDB->getOne( $sSelect )) {
00399 $oEx = oxNew( 'oxVoucherException' );
00400 $oEx->setMessage('EXCEPTION_VOUCHER_NOTAVAILABLEINOTHERORDER');
00401 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00402 throw $oEx;
00403 }
00404 }
00405
00406 return true;
00407 }
00408
00418 protected function _isValidUserGroup( $oUser )
00419 {
00420 $oVoucherSerie = $this->getSerie();
00421 $oUserGroups = $oVoucherSerie->setUserGroups();
00422
00423
00424 if ( !$oUserGroups->count() ) {
00425 return true;
00426 }
00427
00428 if ( $oUser ) {
00429 foreach ( $oUserGroups as $oGroup ) {
00430 if ( $oUser->inGroup( $oGroup->getId() ) ) {
00431 return true;
00432 }
00433 }
00434 }
00435
00436 $oEx = oxNew( 'oxVoucherException' );
00437 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOTVALIDUSERGROUP' );
00438 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00439 throw $oEx;
00440 }
00441
00447 public function getSimpleVoucher()
00448 {
00449 $oVoucher = new oxStdClass();
00450 $oVoucher->sVoucherId = $this->getId();
00451 $oVoucher->sVoucherNr = $this->oxvouchers__oxvouchernr->value;
00452
00453
00454 return $oVoucher;
00455 }
00456
00462 public function getSerie()
00463 {
00464 if ($this->_oSerie !== null) {
00465 return $this->_oSerie;
00466 }
00467 $oSerie = oxNew('oxvoucherserie');
00468 if (!$oSerie->load($this->oxvouchers__oxvoucherserieid->value)) {
00469 throw new oxObjectException();
00470 }
00471 $this->_oSerie = $oSerie;
00472 return $oSerie;
00473 }
00474
00480 protected function _isProductVoucher()
00481 {
00482 $myDB = oxDb::getDb();
00483 $oSerie = $this->getSerie();
00484 $sSelect = "select 1 from oxobject2discount where oxdiscountid = ".$myDB->quote( $oSerie->getId() )." and oxtype = 'oxarticles'";
00485 $blOk = ( bool ) $myDB->getOne( $sSelect );
00486
00487 return $blOk;
00488 }
00489
00495 protected function _isCategoryVoucher()
00496 {
00497 $myDB = oxDb::getDb();
00498 $oSerie = $this->getSerie();
00499 $sSelect = "select 1 from oxobject2discount where oxdiscountid = ". $myDB->quote( $oSerie->getId() )." and oxtype = 'oxcategories'";
00500 $blOk = ( bool ) $myDB->getOne( $sSelect );
00501
00502 return $blOk;
00503 }
00504
00510 protected function _getSerieDiscount( )
00511 {
00512 $oSerie = $this->getSerie();
00513 $oDiscount = oxNew('oxDiscount');
00514
00515 $oDiscount->setId($oSerie->getId());
00516 $oDiscount->oxdiscount__oxshopid = new oxField($oSerie->oxvoucherseries__oxshopid->value);
00517 $oDiscount->oxdiscount__oxactive = new oxField(true);
00518 $oDiscount->oxdiscount__oxactivefrom = new oxField($oSerie->oxvoucherseries__oxbegindate->value);
00519 $oDiscount->oxdiscount__oxactiveto = new oxField($oSerie->oxvoucherseries__oxenddate->value);
00520 $oDiscount->oxdiscount__oxtitle = new oxField($oSerie->oxvoucherseries__oxserienr->value);
00521 $oDiscount->oxdiscount__oxamount = new oxField(1);
00522 $oDiscount->oxdiscount__oxamountto = new oxField(MAX_64BIT_INTEGER);
00523 $oDiscount->oxdiscount__oxprice = new oxField(0);
00524 $oDiscount->oxdiscount__oxpriceto = new oxField(MAX_64BIT_INTEGER);
00525 $oDiscount->oxdiscount__oxaddsumtype = new oxField($oSerie->oxvoucherseries__oxdiscounttype->value=='percent'?'%':'abs');
00526 $oDiscount->oxdiscount__oxaddsum = new oxField($oSerie->oxvoucherseries__oxdiscount->value);
00527 $oDiscount->oxdiscount__oxitmartid = new oxField();
00528 $oDiscount->oxdiscount__oxitmamount = new oxField();
00529 $oDiscount->oxdiscount__oxitmmultiple = new oxField();
00530
00531 return $oDiscount;
00532 }
00533
00541 protected function _getBasketItems($oDiscount = null)
00542 {
00543 if ($this->oxvouchers__oxorderid->value) {
00544 return $this->_getOrderBasketItems($oDiscount);
00545 } elseif ( $this->getSession()->getBasket() ) {
00546 return $this->_getSessionBasketItems($oDiscount);
00547 } else {
00548 return array();
00549 }
00550 }
00551
00559 protected function _getOrderBasketItems($oDiscount = null)
00560 {
00561 if (is_null($oDiscount)) {
00562 $oDiscount = $this->_getSerieDiscount();
00563 }
00564
00565 $oOrder = oxNew('oxorder');
00566 $oOrder->load($this->oxvouchers__oxorderid->value);
00567
00568 $aItems = array();
00569 $iCount = 0;
00570
00571 foreach ( $oOrder->getOrderArticles(true) as $oOrderArticle ) {
00572 if (!$oOrderArticle->skipDiscounts() && $oDiscount->isForBasketItem($oOrderArticle)) {
00573 $aItems[$iCount] = array(
00574 'oxid' => $oOrderArticle->getProductId(),
00575 'price' => $oOrderArticle->oxorderarticles__oxprice->value,
00576 'discount' => $oDiscount->getAbsValue($oOrderArticle->oxorderarticles__oxprice->value),
00577 'amount' => $oOrderArticle->oxorderarticles__oxamount->value,
00578 );
00579 $iCount ++;
00580 }
00581 }
00582
00583 return $aItems;
00584 }
00585
00593 protected function _getSessionBasketItems($oDiscount = null)
00594 {
00595 if (is_null($oDiscount)) {
00596 $oDiscount = $this->_getSerieDiscount();
00597 }
00598
00599 $oBasket = $this->getSession()->getBasket();
00600 $aItems = array();
00601 $iCount = 0;
00602
00603 foreach ( $oBasket->getContents() as $oBasketItem ) {
00604 if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle() ) && !$oArticle->skipDiscounts() && $oDiscount->isForBasketItem($oArticle) ) {
00605
00606 $aItems[$iCount] = array(
00607 'oxid' => $oArticle->getId(),
00608 'price' => $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice(),
00609 'discount' => $oDiscount->getAbsValue($oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice()),
00610 'amount' => $oBasketItem->getAmount(),
00611 );
00612
00613 $iCount ++;
00614 }
00615 }
00616
00617 return $aItems;
00618 }
00619
00629 protected function _getGenericDiscoutValue( $dPrice )
00630 {
00631 $oSerie = $this->getSerie();
00632 if ( $oSerie->oxvoucherseries__oxdiscounttype->value == 'absolute' ) {
00633 $oCur = $this->getConfig()->getActShopCurrencyObject();
00634 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value * $oCur->rate;
00635 } else {
00636 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value / 100 * $dPrice;
00637 }
00638
00639 if ( $dDiscount > $dPrice ) {
00640 $oEx = oxNew( 'oxVoucherException' );
00641 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00642 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00643 throw $oEx;
00644 }
00645
00646 return $dDiscount;
00647 }
00648
00658 protected function _getProductDiscoutValue( $dPrice )
00659 {
00660 $oDiscount = $this->_getSerieDiscount();
00661 $aBasketItems = $this->_getBasketItems($oDiscount);
00662
00663
00664 if (!count($aBasketItems) && !$this->isAdmin() ) {
00665 $oEx = oxNew( 'oxVoucherException' );
00666 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00667 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00668 throw $oEx;
00669 }
00670
00671 $oSerie = $this->getSerie();
00672
00673 $oVoucherPrice = oxNew('oxPrice');
00674 $oDiscountPrice = oxNew('oxPrice');
00675 $oProductPrice = oxNew('oxPrice');
00676 $oProductTotal = oxNew('oxPrice');
00677
00678 foreach ( $aBasketItems as $aBasketItem ) {
00679
00680 $oDiscountPrice->setPrice($aBasketItem['discount']);
00681 $oProductPrice->setPrice($aBasketItem['price']);
00682
00683
00684 if (!$oSerie->oxvoucherseries__oxcalculateonce->value) {
00685 $oDiscountPrice->multiply($aBasketItem['amount']);
00686 $oProductPrice->multiply($aBasketItem['amount']);
00687 }
00688
00689 $oVoucherPrice->add($oDiscountPrice->getBruttoPrice());
00690 $oProductTotal->add($oProductPrice->getBruttoPrice());
00691 }
00692
00693 $dVoucher = $oVoucherPrice->getBruttoPrice();
00694 $dProduct = $oProductTotal->getBruttoPrice();
00695
00696 if ( $dVoucher > $dProduct ) {
00697 return $dProduct;
00698 }
00699
00700 return $dVoucher;
00701 }
00702
00712 protected function _getCategoryDiscoutValue( $dPrice )
00713 {
00714 $oDiscount = $this->_getSerieDiscount();
00715 $aBasketItems = $this->_getBasketItems( $oDiscount );
00716
00717
00718 if ( !count( $aBasketItems ) && !$this->isAdmin() ) {
00719 $oEx = oxNew( 'oxVoucherException' );
00720 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00721 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00722 throw $oEx;
00723 }
00724
00725 $oProductPrice = oxNew('oxPrice');
00726 $oProductTotal = oxNew('oxPrice');
00727
00728 foreach ( $aBasketItems as $aBasketItem ) {
00729 $oProductPrice->setPrice( $aBasketItem['price'] );
00730 $oProductPrice->multiply( $aBasketItem['amount'] );
00731 $oProductTotal->add( $oProductPrice->getBruttoPrice() );
00732 }
00733
00734 $dProduct = $oProductTotal->getBruttoPrice();
00735 $dVoucher = $oDiscount->getAbsValue( $dProduct );
00736 return ( $dVoucher > $dProduct ) ? $dProduct : $dVoucher;
00737 }
00738
00746 public function __get( $sName )
00747 {
00748 switch ( $sName ) {
00749
00750
00751 case 'sVoucherId':
00752 return $this->getId();
00753 break;
00754 case 'sVoucherNr':
00755 return $this->oxvouchers__oxvouchernr;
00756 break;
00757 case 'fVoucherdiscount':
00758 return $this->oxvouchers__oxdiscount;
00759 break;
00760 }
00761 return parent::__get($sName);
00762 }
00763 }