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
00053 $sQ = "select {$sViewName}.* from {$sViewName}, {$sSeriesViewName} where
00054 {$sSeriesViewName}.oxid = {$sViewName}.oxvoucherserieid and
00055 {$sViewName}.oxvouchernr = " . oxDb::getDb()->quote( $sVoucherNr ) . " and ";
00056
00057 if ( is_array( $aVouchers ) ) {
00058 foreach ( $aVouchers as $sVoucherId => $sSkipVoucherNr ) {
00059 $sQ .= "{$sViewName}.oxid != " . oxDb::getDb()->quote( $sVoucherId ) . " and ";
00060 }
00061 }
00062 $sQ .= "( {$sViewName}.oxorderid is NULL || {$sViewName}.oxorderid = '' ) ";
00063
00064
00065 if ( $blCheckavalability ) {
00066 $iTime = time() - 3600 * 3;
00067 $sQ .= " and {$sViewName}.oxreserved < '{$iTime}' ";
00068 }
00069
00070 $sQ .= " limit 1";
00071
00072 if ( ! ( $oRet = $this->assignRecord( $sQ ) ) ) {
00073 $oEx = oxNew( 'oxVoucherException' );
00074 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOVOUCHER' );
00075 $oEx->setVoucherNr( $sVoucherNr );
00076 throw $oEx;
00077 }
00078 }
00079
00080 return $oRet;
00081 }
00082
00092 public function markAsUsed( $sOrderId, $sUserId, $dDiscount )
00093 {
00094
00095 if ( $this->oxvouchers__oxid->value ) {
00096 $this->oxvouchers__oxorderid->setValue($sOrderId);
00097 $this->oxvouchers__oxuserid->setValue($sUserId);
00098 $this->oxvouchers__oxdiscount->setValue($dDiscount);
00099 $this->oxvouchers__oxdateused->setValue(date( "Y-m-d", oxUtilsDate::getInstance()->getTime() ));
00100 $this->save();
00101 }
00102 }
00103
00109 public function markAsReserved()
00110 {
00111
00112 $sVoucherID = $this->oxvouchers__oxid->value;
00113
00114 if ( $sVoucherID ) {
00115 $sQ = "update oxvouchers set oxreserved = " . time() . " where oxid = " . oxDb::getDb()->quote( $sVoucherID );
00116 oxDb::getDb()->Execute( $sQ );
00117 }
00118 }
00119
00125 public function unMarkAsReserved()
00126 {
00127
00128 $sVoucherID = $this->oxvouchers__oxid->value;
00129
00130 if ( $sVoucherID ) {
00131 $sQ = "update oxvouchers set oxreserved = 0 where oxid = " . oxDb::getDb()->quote( $sVoucherID );
00132 oxDb::getDb()->Execute($sQ);
00133 }
00134 }
00135
00145 public function getDiscountValue( $dPrice )
00146 {
00147 if ($this->_isProductVoucher()) {
00148 return $this->_getProductDiscoutValue( $dPrice );
00149 } elseif ($this->_isCategoryVoucher()) {
00150 return $this->_getCategoryDiscoutValue( $dPrice );
00151 } else {
00152 return $this->_getGenericDiscoutValue( $dPrice );
00153 }
00154 }
00155
00156
00167 public function checkVoucherAvailability( $aVouchers, $dPrice )
00168 {
00169 $this->_isAvailableWithSameSeries( $aVouchers );
00170 $this->_isAvailableWithOtherSeries( $aVouchers );
00171 $this->_isValidDate();
00172 $this->_isAvailablePrice( $dPrice );
00173 $this->_isNotReserved();
00174
00175
00176 return true;
00177 }
00178
00190 public function checkBasketVoucherAvailability( $aVouchers, $dPrice )
00191 {
00192 $this->_isAvailableWithSameSeries( $aVouchers );
00193 $this->_isAvailableWithOtherSeries( $aVouchers );
00194 $this->_isValidDate();
00195 $this->_isAvailablePrice( $dPrice );
00196
00197
00198 return true;
00199 }
00200
00210 protected function _isAvailablePrice( $dPrice )
00211 {
00212 if ( $this->getDiscountValue( $dPrice ) < 0 ) {
00213 $oEx = oxNew( 'oxVoucherException' );
00214 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00215 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00216 throw $oEx;
00217 }
00218 $oSerie = $this->getSerie();
00219 $oCur = $this->getConfig()->getActShopCurrencyObject();
00220 if ( $oSerie->oxvoucherseries__oxminimumvalue->value && $dPrice < ($oSerie->oxvoucherseries__oxminimumvalue->value*$oCur->rate) ) {
00221 $oEx = oxNew( 'oxVoucherException' );
00222 $oEx->setMessage('EXCEPTION_VOUCHER_INCORRECTPRICE');
00223 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00224 throw $oEx;
00225 }
00226
00227 return true;
00228 }
00229
00241 protected function _isAvailableWithSameSeries( $aVouchers )
00242 {
00243 if ( is_array( $aVouchers ) ) {
00244 $sId = $this->getId();
00245 if (isset($aVouchers[$sId])) {
00246 unset($aVouchers[$sId]);
00247 }
00248 $oSerie = $this->getSerie();
00249 if (!$oSerie->oxvoucherseries__oxallowsameseries->value) {
00250 foreach ( $aVouchers as $voucherId => $voucherNr ) {
00251 $oVoucher = oxNew( 'oxvoucher' );
00252 $oVoucher->load($voucherId);
00253 if ( $this->oxvouchers__oxvoucherserieid->value == $oVoucher->oxvouchers__oxvoucherserieid->value ) {
00254 $oEx = oxNew( 'oxVoucherException' );
00255 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDSAMESERIES');
00256 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00257 throw $oEx;
00258 }
00259 }
00260 }
00261 }
00262
00263 return true;
00264 }
00265
00276 protected function _isAvailableWithOtherSeries( $aVouchers )
00277 {
00278 if ( is_array( $aVouchers ) && count($aVouchers) ) {
00279 $oSerie = $this->getSerie();
00280 $sIds = '\''.implode('\',\'', array_keys($aVouchers)).'\'';
00281 $blAvailable = true;
00282 if (!$oSerie->oxvoucherseries__oxallowotherseries->value) {
00283
00284 $sSql = "select 1 from oxvouchers where oxvouchers.oxid in ($sIds) and ";
00285 $sSql .= "oxvouchers.oxvoucherserieid != " . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value ) ;
00286 $blAvailable &= !oxDb::getDb()->getOne($sSql);
00287 } else {
00288
00289 $sSql = "select 1 from oxvouchers left join oxvoucherseries on oxvouchers.oxvoucherserieid=oxvoucherseries.oxid ";
00290 $sSql .= "where oxvouchers.oxid in ($sIds) and oxvouchers.oxvoucherserieid != " . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value );
00291 $sSql .= "and not oxvoucherseries.oxallowotherseries";
00292 $blAvailable &= !oxDb::getDb()->getOne($sSql);
00293 }
00294 if ( !$blAvailable ) {
00295 $oEx = oxNew( 'oxVoucherException' );
00296 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDOTHERSERIES');
00297 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00298 throw $oEx;
00299 }
00300 }
00301
00302 return true;
00303 }
00304
00312 protected function _isValidDate()
00313 {
00314 $oSerie = $this->getSerie();
00315
00316 $sDefTimeStamp = oxUtilsDate::getInstance()->formatDBDate( '-' );
00317 if ( $oSerie->oxvoucherseries__oxbegindate->value == $sDefTimeStamp &&
00318 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00319 return true;
00320 }
00321
00322 if ( ( strtotime( $oSerie->oxvoucherseries__oxbegindate->value ) < time() &&
00323 strtotime( $oSerie->oxvoucherseries__oxenddate->value ) > time() ) ||
00324 !$oSerie->oxvoucherseries__oxenddate->value ||
00325 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00326 return true;
00327 }
00328
00329 $oEx = oxNew( 'oxVoucherException' );
00330 $oEx->setMessage('EXCEPTION_VOUCHER_ISNOTVALIDDATE');
00331 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00332 throw $oEx;
00333 }
00334
00342 protected function _isNotReserved()
00343 {
00344
00345 if ( $this->oxvouchers__oxreserved->value < time() - 3600 * 3 ) {
00346 return true;
00347 }
00348
00349 $oEx = oxNew( 'oxVoucherException' );
00350 $oEx->setMessage('EXCEPTION_VOUCHER_ISRESERVED');
00351 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00352 throw $oEx;
00353 }
00354
00355
00365 public function checkUserAvailability( $oUser )
00366 {
00367
00368 $this->_isAvailableInOtherOrder( $oUser );
00369 $this->_isValidUserGroup( $oUser );
00370
00371
00372 return true;
00373 }
00374
00384 protected function _isAvailableInOtherOrder( $oUser )
00385 {
00386 $oSerie = $this->getSerie();
00387 if ( !$oSerie->oxvoucherseries__oxallowuseanother->value ) {
00388
00389 $sSelect = 'select count(*) from '.$this->getViewName().' where oxuserid = '. oxDb::getDb()->quote( $oUser->oxuser__oxid->value ) . ' and ';
00390 $sSelect .= 'oxvoucherserieid = ' . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value ) . ' and ';
00391 $sSelect .= 'oxorderid is not NULL and oxorderid != "" ';
00392
00393 if ( oxDb::getDb()->getOne( $sSelect )) {
00394 $oEx = oxNew( 'oxVoucherException' );
00395 $oEx->setMessage('EXCEPTION_VOUCHER_NOTAVAILABLEINOTHERORDER');
00396 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00397 throw $oEx;
00398 }
00399 }
00400
00401 return true;
00402 }
00403
00413 protected function _isValidUserGroup( $oUser )
00414 {
00415 $oVoucherSerie = $this->getSerie();
00416 $oUserGroups = $oVoucherSerie->setUserGroups();
00417
00418
00419 if ( !$oUserGroups->count() ) {
00420 return true;
00421 }
00422
00423 if ( $oUser ) {
00424 foreach ( $oUserGroups as $oGroup ) {
00425 if ( $oUser->inGroup( $oGroup->getId() ) ) {
00426 return true;
00427 }
00428 }
00429 }
00430
00431 $oEx = oxNew( 'oxVoucherException' );
00432 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOTVALIDUSERGROUP' );
00433 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00434 throw $oEx;
00435 }
00436
00442 public function getSimpleVoucher()
00443 {
00444 $oVoucher = new oxStdClass();
00445 $oVoucher->sVoucherId = $this->getId();
00446 $oVoucher->sVoucherNr = $this->oxvouchers__oxvouchernr->value;
00447
00448
00449 return $oVoucher;
00450 }
00451
00457 public function getSerie()
00458 {
00459 if ($this->_oSerie !== null) {
00460 return $this->_oSerie;
00461 }
00462 $oSerie = oxNew('oxvoucherserie');
00463 if (!$oSerie->load($this->oxvouchers__oxvoucherserieid->value)) {
00464 throw new oxObjectException();
00465 }
00466 $this->_oSerie = $oSerie;
00467 return $oSerie;
00468 }
00469
00475 protected function _isProductVoucher()
00476 {
00477 $myDB = oxDb::getDb();
00478 $oSerie = $this->getSerie();
00479 $sSelect = "select 1 from oxobject2discount where oxdiscountid = '".$oSerie->getId()."' and oxtype = 'oxarticles'";
00480 $blOk = ( bool ) $myDB->getOne( $sSelect );
00481
00482 return $blOk;
00483 }
00484
00490 protected function _isCategoryVoucher()
00491 {
00492 $myDB = oxDb::getDb();
00493 $oSerie = $this->getSerie();
00494 $sSelect = "select 1 from oxobject2discount where oxdiscountid = '".$oSerie->getId()."' and oxtype = 'oxcategories'";
00495 $blOk = ( bool ) $myDB->getOne( $sSelect );
00496
00497 return $blOk;
00498 }
00499
00505 protected function _getSerieDiscount( )
00506 {
00507 $oSerie = $this->getSerie();
00508 $oDiscount = oxNew('oxDiscount');
00509
00510 $oDiscount->setId($oSerie->getId());
00511 $oDiscount->oxdiscount__oxshopid = new oxField($oSerie->oxvoucherseries__oxshopid->value);
00512 $oDiscount->oxdiscount__oxactive = new oxField(true);
00513 $oDiscount->oxdiscount__oxactivefrom = new oxField($oSerie->oxvoucherseries__oxbegindate->value);
00514 $oDiscount->oxdiscount__oxactiveto = new oxField($oSerie->oxvoucherseries__oxenddate->value);
00515 $oDiscount->oxdiscount__oxtitle = new oxField($oSerie->oxvoucherseries__oxserienr->value);
00516 $oDiscount->oxdiscount__oxamount = new oxField(1);
00517 $oDiscount->oxdiscount__oxamountto = new oxField(MAX_64BIT_INTEGER);
00518 $oDiscount->oxdiscount__oxprice = new oxField(0);
00519 $oDiscount->oxdiscount__oxpriceto = new oxField(MAX_64BIT_INTEGER);
00520 $oDiscount->oxdiscount__oxaddsumtype = new oxField($oSerie->oxvoucherseries__oxdiscounttype->value=='percent'?'%':'abs');
00521 $oDiscount->oxdiscount__oxaddsum = new oxField($oSerie->oxvoucherseries__oxdiscount->value);
00522 $oDiscount->oxdiscount__oxitmartid = new oxField();
00523 $oDiscount->oxdiscount__oxitmamount = new oxField();
00524 $oDiscount->oxdiscount__oxitmmultiple = new oxField();
00525
00526 return $oDiscount;
00527 }
00528
00536 protected function _getBasketItems($oDiscount = null)
00537 {
00538 if ($this->oxvouchers__oxorderid->value) {
00539 return $this->_getOrderBasketItems($oDiscount);
00540 } elseif ( $this->getSession()->getBasket() ) {
00541 return $this->_getSessionBasketItems($oDiscount);
00542 } else {
00543 return array();
00544 }
00545 }
00546
00554 protected function _getOrderBasketItems($oDiscount = null)
00555 {
00556 if (is_null($oDiscount)) {
00557 $oDiscount = $this->_getSerieDiscount();
00558 }
00559
00560 $oOrder = oxNew('oxorder');
00561 $oOrder->load($this->oxvouchers__oxorderid->value);
00562
00563 $aItems = array();
00564 $iCount = 0;
00565
00566 foreach ( $oOrder->getOrderArticles(true) as $oOrderArticle ) {
00567 if (!$oOrderArticle->skipDiscounts() && $oDiscount->isForBasketItem($oOrderArticle)) {
00568 $aItems[$iCount] = array(
00569 'oxid' => $oOrderArticle->getProductId(),
00570 'price' => $oOrderArticle->oxorderarticles__oxprice->value,
00571 'discount' => $oDiscount->getAbsValue($oOrderArticle->oxorderarticles__oxprice->value),
00572 'amount' => $oOrderArticle->oxorderarticles__oxamount->value,
00573 );
00574 $iCount ++;
00575 }
00576 }
00577
00578 return $aItems;
00579 }
00580
00588 protected function _getSessionBasketItems($oDiscount = null)
00589 {
00590 if (is_null($oDiscount)) {
00591 $oDiscount = $this->_getSerieDiscount();
00592 }
00593
00594 $oBasket = $this->getSession()->getBasket();
00595 $aItems = array();
00596 $iCount = 0;
00597
00598 foreach ( $oBasket->getContents() as $oBasketItem ) {
00599 if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle() ) && !$oArticle->skipDiscounts() && $oDiscount->isForBasketItem($oArticle) ) {
00600
00601 $aItems[$iCount] = array(
00602 'oxid' => $oArticle->getId(),
00603 'price' => $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice(),
00604 'discount' => $oDiscount->getAbsValue($oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice()),
00605 'amount' => $oBasketItem->getAmount(),
00606 );
00607
00608 $iCount ++;
00609 }
00610 }
00611
00612 return $aItems;
00613 }
00614
00624 protected function _getGenericDiscoutValue( $dPrice )
00625 {
00626 $oSerie = $this->getSerie();
00627 if ( $oSerie->oxvoucherseries__oxdiscounttype->value == 'absolute' ) {
00628 $oCur = $this->getConfig()->getActShopCurrencyObject();
00629 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value * $oCur->rate;
00630 } else {
00631 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value / 100 * $dPrice;
00632 }
00633
00634 if ( $dDiscount > $dPrice ) {
00635 $oEx = oxNew( 'oxVoucherException' );
00636 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00637 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00638 throw $oEx;
00639 }
00640
00641 return $dDiscount;
00642 }
00643
00653 protected function _getProductDiscoutValue( $dPrice )
00654 {
00655 $oDiscount = $this->_getSerieDiscount();
00656 $aBasketItems = $this->_getBasketItems($oDiscount);
00657
00658
00659 if (!count($aBasketItems) && !$this->isAdmin() ) {
00660 $oEx = oxNew( 'oxVoucherException' );
00661 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00662 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00663 throw $oEx;
00664 }
00665
00666 $oSerie = $this->getSerie();
00667
00668 $oVoucherPrice = oxNew('oxPrice');
00669 $oDiscountPrice = oxNew('oxPrice');
00670 $oProductPrice = oxNew('oxPrice');
00671 $oProductTotal = oxNew('oxPrice');
00672
00673 foreach ( $aBasketItems as $aBasketItem ) {
00674
00675 $oDiscountPrice->setPrice($aBasketItem['discount']);
00676 $oProductPrice->setPrice($aBasketItem['price']);
00677
00678
00679 if (!$oSerie->oxvoucherseries__oxcalculateonce->value) {
00680 $oDiscountPrice->multiply($aBasketItem['amount']);
00681 $oProductPrice->multiply($aBasketItem['amount']);
00682 }
00683
00684 $oVoucherPrice->add($oDiscountPrice->getBruttoPrice());
00685 $oProductTotal->add($oProductPrice->getBruttoPrice());
00686 }
00687
00688 $dVoucher = $oVoucherPrice->getBruttoPrice();
00689 $dProduct = $oProductTotal->getBruttoPrice();
00690
00691 if ( $dVoucher > $dProduct ) {
00692 return $dProduct;
00693 }
00694
00695 return $dVoucher;
00696 }
00697
00707 protected function _getCategoryDiscoutValue( $dPrice )
00708 {
00709 $oDiscount = $this->_getSerieDiscount();
00710 $aBasketItems = $this->_getBasketItems( $oDiscount );
00711
00712
00713 if ( !count( $aBasketItems ) && !$this->isAdmin() ) {
00714 $oEx = oxNew( 'oxVoucherException' );
00715 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00716 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00717 throw $oEx;
00718 }
00719
00720 $oProductPrice = oxNew('oxPrice');
00721 $oProductTotal = oxNew('oxPrice');
00722
00723 foreach ( $aBasketItems as $aBasketItem ) {
00724 $oProductPrice->setPrice( $aBasketItem['price'] );
00725 $oProductPrice->multiply( $aBasketItem['amount'] );
00726 $oProductTotal->add( $oProductPrice->getBruttoPrice() );
00727 }
00728
00729 $dProduct = $oProductTotal->getBruttoPrice();
00730 $dVoucher = $oDiscount->getAbsValue( $dProduct );
00731 return ( $dVoucher > $dProduct ) ? $dProduct : $dVoucher;
00732 }
00733
00741 public function __get( $sName )
00742 {
00743 switch ( $sName ) {
00744
00745
00746 case 'sVoucherId':
00747 return $this->getId();
00748 break;
00749 case 'sVoucherNr':
00750 return $this->oxvouchers__oxvouchernr;
00751 break;
00752 case 'fVoucherdiscount':
00753 return $this->oxvouchers__oxdiscount;
00754 break;
00755 }
00756 return parent::__get($sName);
00757 }
00758 }