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 $oDb = oxDb::getDb();
00053
00054 $sQ = "select {$sViewName}.* from {$sViewName}, {$sSeriesViewName} where
00055 {$sSeriesViewName}.oxid = {$sViewName}.oxvoucherserieid and
00056 {$sViewName}.oxvouchernr = " . $oDb->quote( $sVoucherNr ) . " and ";
00057
00058 if ( is_array( $aVouchers ) ) {
00059 foreach ( $aVouchers as $sVoucherId => $sSkipVoucherNr ) {
00060 $sQ .= "{$sViewName}.oxid != " . $oDb->quote( $sVoucherId ) . " and ";
00061 }
00062 }
00063 $sQ .= "( {$sViewName}.oxorderid is NULL || {$sViewName}.oxorderid = '' ) ";
00064 $sQ .= " and ( {$sViewName}.oxdateused is NULL || {$sViewName}.oxdateused = 0 ) ";
00065
00066
00067 if ( $blCheckavalability ) {
00068 $iTime = time() - 3600 * 3;
00069 $sQ .= " and {$sViewName}.oxreserved < '{$iTime}' ";
00070 }
00071
00072 $sQ .= " limit 1";
00073
00074 if ( ! ( $oRet = $this->assignRecord( $sQ ) ) ) {
00075 $oEx = oxNew( 'oxVoucherException' );
00076 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOVOUCHER' );
00077 $oEx->setVoucherNr( $sVoucherNr );
00078 throw $oEx;
00079 }
00080 }
00081
00082 return $oRet;
00083 }
00084
00094 public function markAsUsed( $sOrderId, $sUserId, $dDiscount )
00095 {
00096
00097 if ( $this->oxvouchers__oxid->value ) {
00098 $this->oxvouchers__oxorderid->setValue($sOrderId);
00099 $this->oxvouchers__oxuserid->setValue($sUserId);
00100 $this->oxvouchers__oxdiscount->setValue($dDiscount);
00101 $this->oxvouchers__oxdateused->setValue(date( "Y-m-d", oxUtilsDate::getInstance()->getTime() ));
00102 $this->save();
00103 }
00104 }
00105
00111 public function markAsReserved()
00112 {
00113
00114 $sVoucherID = $this->oxvouchers__oxid->value;
00115
00116 if ( $sVoucherID ) {
00117 $oDb = oxDb::getDb();
00118 $sQ = "update oxvouchers set oxreserved = " . time() . " where oxid = " . $oDb->quote( $sVoucherID );
00119 $oDb->Execute( $sQ );
00120 }
00121 }
00122
00128 public function unMarkAsReserved()
00129 {
00130
00131 $sVoucherID = $this->oxvouchers__oxid->value;
00132
00133 if ( $sVoucherID ) {
00134 $oDb = oxDb::getDb();
00135 $sQ = "update oxvouchers set oxreserved = 0 where oxid = " . $oDb->quote( $sVoucherID );
00136 $oDb->Execute($sQ);
00137 }
00138 }
00139
00149 public function getDiscountValue( $dPrice )
00150 {
00151 if ($this->_isProductVoucher()) {
00152 return $this->_getProductDiscoutValue( (double) $dPrice );
00153 } elseif ($this->_isCategoryVoucher()) {
00154 return $this->_getCategoryDiscoutValue( (double) $dPrice );
00155 } else {
00156 return $this->_getGenericDiscoutValue( (double) $dPrice );
00157 }
00158 }
00159
00160
00171 public function checkVoucherAvailability( $aVouchers, $dPrice )
00172 {
00173 $this->_isAvailableWithSameSeries( $aVouchers );
00174 $this->_isAvailableWithOtherSeries( $aVouchers );
00175 $this->_isValidDate();
00176 $this->_isAvailablePrice( $dPrice );
00177 $this->_isNotReserved();
00178
00179
00180 return true;
00181 }
00182
00194 public function checkBasketVoucherAvailability( $aVouchers, $dPrice )
00195 {
00196 $this->_isAvailableWithSameSeries( $aVouchers );
00197 $this->_isAvailableWithOtherSeries( $aVouchers );
00198 $this->_isValidDate();
00199 $this->_isAvailablePrice( $dPrice );
00200
00201
00202 return true;
00203 }
00204
00214 protected function _isAvailablePrice( $dPrice )
00215 {
00216 if ( $this->getDiscountValue( $dPrice ) < 0 ) {
00217 $oEx = oxNew( 'oxVoucherException' );
00218 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00219 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00220 throw $oEx;
00221 }
00222 $oSerie = $this->getSerie();
00223 $oCur = $this->getConfig()->getActShopCurrencyObject();
00224 if ( $oSerie->oxvoucherseries__oxminimumvalue->value && $dPrice < ($oSerie->oxvoucherseries__oxminimumvalue->value*$oCur->rate) ) {
00225 $oEx = oxNew( 'oxVoucherException' );
00226 $oEx->setMessage('EXCEPTION_VOUCHER_INCORRECTPRICE');
00227 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00228 throw $oEx;
00229 }
00230
00231 return true;
00232 }
00233
00245 protected function _isAvailableWithSameSeries( $aVouchers )
00246 {
00247 if ( is_array( $aVouchers ) ) {
00248 $sId = $this->getId();
00249 if (isset($aVouchers[$sId])) {
00250 unset($aVouchers[$sId]);
00251 }
00252 $oSerie = $this->getSerie();
00253 if (!$oSerie->oxvoucherseries__oxallowsameseries->value) {
00254 foreach ( $aVouchers as $voucherId => $voucherNr ) {
00255 $oVoucher = oxNew( 'oxvoucher' );
00256 $oVoucher->load($voucherId);
00257 if ( $this->oxvouchers__oxvoucherserieid->value == $oVoucher->oxvouchers__oxvoucherserieid->value ) {
00258 $oEx = oxNew( 'oxVoucherException' );
00259 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDSAMESERIES');
00260 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00261 throw $oEx;
00262 }
00263 }
00264 }
00265 }
00266
00267 return true;
00268 }
00269
00280 protected function _isAvailableWithOtherSeries( $aVouchers )
00281 {
00282 if ( is_array( $aVouchers ) && count($aVouchers) ) {
00283 $oSerie = $this->getSerie();
00284 $sIds = implode(',', oxDb::getInstance()->quoteArray( array_keys( $aVouchers ) ) );
00285 $blAvailable = true;
00286 $oDb = oxDb::getDb();
00287 if (!$oSerie->oxvoucherseries__oxallowotherseries->value) {
00288
00289 $sSql = "select 1 from oxvouchers where oxvouchers.oxid in ($sIds) and ";
00290 $sSql .= "oxvouchers.oxvoucherserieid != " . $oDb->quote( $this->oxvouchers__oxvoucherserieid->value ) ;
00291 $blAvailable &= !$oDb->getOne($sSql);
00292 } else {
00293
00294 $sSql = "select 1 from oxvouchers left join oxvoucherseries on oxvouchers.oxvoucherserieid=oxvoucherseries.oxid ";
00295 $sSql .= "where oxvouchers.oxid in ($sIds) and oxvouchers.oxvoucherserieid != " . $oDb->quote( $this->oxvouchers__oxvoucherserieid->value );
00296 $sSql .= "and not oxvoucherseries.oxallowotherseries";
00297 $blAvailable &= !$oDb->getOne($sSql);
00298 }
00299 if ( !$blAvailable ) {
00300 $oEx = oxNew( 'oxVoucherException' );
00301 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDOTHERSERIES');
00302 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00303 throw $oEx;
00304 }
00305 }
00306
00307 return true;
00308 }
00309
00317 protected function _isValidDate()
00318 {
00319 $oSerie = $this->getSerie();
00320
00321
00322 $iTomorrow = mktime( 0, 0, 0, date( "m" ), date( "d" )+1, date( "Y" ) );
00323 $iYesterday = mktime( 0, 0, 0, date( "m" ), date( "d" )-1, date( "Y" ) );
00324
00325
00326 $iFrom = ( (int)$oSerie->oxvoucherseries__oxbegindate->value ) ?
00327 strtotime( $oSerie->oxvoucherseries__oxbegindate->value ) : $iYesterday;
00328
00329
00330 $iTo = ( (int)$oSerie->oxvoucherseries__oxenddate->value ) ?
00331 strtotime( $oSerie->oxvoucherseries__oxenddate->value ) : $iTomorrow;
00332
00333 if ( $iFrom < time() && $iTo > time() ) {
00334 return true;
00335 }
00336
00337 $oEx = oxNew( 'oxVoucherException' );
00338 $oEx->setMessage('EXCEPTION_VOUCHER_ISNOTVALIDDATE');
00339 if ( $iFrom > time() && $iTo > time() ) {
00340 $oEx->setMessage('ERROR_MESSAGE_VOUCHER_NOVOUCHER');
00341 }
00342 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00343 throw $oEx;
00344 }
00345
00353 protected function _isNotReserved()
00354 {
00355
00356 if ( $this->oxvouchers__oxreserved->value < time() - 3600 * 3 ) {
00357 return true;
00358 }
00359
00360 $oEx = oxNew( 'oxVoucherException' );
00361 $oEx->setMessage('EXCEPTION_VOUCHER_ISRESERVED');
00362 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00363 throw $oEx;
00364 }
00365
00366
00376 public function checkUserAvailability( $oUser )
00377 {
00378
00379 $this->_isAvailableInOtherOrder( $oUser );
00380 $this->_isValidUserGroup( $oUser );
00381
00382
00383 return true;
00384 }
00385
00395 protected function _isAvailableInOtherOrder( $oUser )
00396 {
00397 $oSerie = $this->getSerie();
00398 if ( !$oSerie->oxvoucherseries__oxallowuseanother->value ) {
00399
00400 $oDb = oxDb::getDb();
00401 $sSelect = 'select count(*) from '.$this->getViewName().' where oxuserid = '. $oDb->quote( $oUser->oxuser__oxid->value ) . ' and ';
00402 $sSelect .= 'oxvoucherserieid = ' . $oDb->quote( $this->oxvouchers__oxvoucherserieid->value ) . ' and ';
00403 $sSelect .= '((oxorderid is not NULL and oxorderid != "") or (oxdateused is not NULL and oxdateused != 0)) ';
00404
00405 if ( $oDb->getOne( $sSelect )) {
00406 $oEx = oxNew( 'oxVoucherException' );
00407 $oEx->setMessage('EXCEPTION_VOUCHER_NOTAVAILABLEINOTHERORDER');
00408 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00409 throw $oEx;
00410 }
00411 }
00412
00413 return true;
00414 }
00415
00425 protected function _isValidUserGroup( $oUser )
00426 {
00427 $oVoucherSerie = $this->getSerie();
00428 $oUserGroups = $oVoucherSerie->setUserGroups();
00429
00430
00431 if ( !$oUserGroups->count() ) {
00432 return true;
00433 }
00434
00435 if ( $oUser ) {
00436 foreach ( $oUserGroups as $oGroup ) {
00437 if ( $oUser->inGroup( $oGroup->getId() ) ) {
00438 return true;
00439 }
00440 }
00441 }
00442
00443 $oEx = oxNew( 'oxVoucherException' );
00444 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOTVALIDUSERGROUP' );
00445 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00446 throw $oEx;
00447 }
00448
00454 public function getSimpleVoucher()
00455 {
00456 $oVoucher = new oxStdClass();
00457 $oVoucher->sVoucherId = $this->getId();
00458 $oVoucher->sVoucherNr = $this->oxvouchers__oxvouchernr->value;
00459
00460
00461 return $oVoucher;
00462 }
00463
00469 public function getSerie()
00470 {
00471 if ($this->_oSerie !== null) {
00472 return $this->_oSerie;
00473 }
00474 $oSerie = oxNew('oxvoucherserie');
00475 if (!$oSerie->load($this->oxvouchers__oxvoucherserieid->value)) {
00476 throw oxNew( "oxObjectException" );
00477 }
00478 $this->_oSerie = $oSerie;
00479 return $oSerie;
00480 }
00481
00487 protected function _isProductVoucher()
00488 {
00489 $oDb = oxDb::getDb();
00490 $oSerie = $this->getSerie();
00491 $sSelect = "select 1 from oxobject2discount where oxdiscountid = ".$oDb->quote( $oSerie->getId() )." and oxtype = 'oxarticles'";
00492 $blOk = ( bool ) $oDb->getOne( $sSelect );
00493
00494 return $blOk;
00495 }
00496
00502 protected function _isCategoryVoucher()
00503 {
00504 $oDb = oxDb::getDb();
00505 $oSerie = $this->getSerie();
00506 $sSelect = "select 1 from oxobject2discount where oxdiscountid = ". $oDb->quote( $oSerie->getId() )." and oxtype = 'oxcategories'";
00507 $blOk = ( bool ) $oDb->getOne( $sSelect );
00508
00509 return $blOk;
00510 }
00511
00517 protected function _getSerieDiscount( )
00518 {
00519 $oSerie = $this->getSerie();
00520 $oDiscount = oxNew('oxDiscount');
00521
00522 $oDiscount->setId($oSerie->getId());
00523 $oDiscount->oxdiscount__oxshopid = new oxField($oSerie->oxvoucherseries__oxshopid->value);
00524 $oDiscount->oxdiscount__oxactive = new oxField(true);
00525 $oDiscount->oxdiscount__oxactivefrom = new oxField($oSerie->oxvoucherseries__oxbegindate->value);
00526 $oDiscount->oxdiscount__oxactiveto = new oxField($oSerie->oxvoucherseries__oxenddate->value);
00527 $oDiscount->oxdiscount__oxtitle = new oxField($oSerie->oxvoucherseries__oxserienr->value);
00528 $oDiscount->oxdiscount__oxamount = new oxField(1);
00529 $oDiscount->oxdiscount__oxamountto = new oxField(MAX_64BIT_INTEGER);
00530 $oDiscount->oxdiscount__oxprice = new oxField(0);
00531 $oDiscount->oxdiscount__oxpriceto = new oxField(MAX_64BIT_INTEGER);
00532 $oDiscount->oxdiscount__oxaddsumtype = new oxField($oSerie->oxvoucherseries__oxdiscounttype->value=='percent'?'%':'abs');
00533 $oDiscount->oxdiscount__oxaddsum = new oxField($oSerie->oxvoucherseries__oxdiscount->value);
00534 $oDiscount->oxdiscount__oxitmartid = new oxField();
00535 $oDiscount->oxdiscount__oxitmamount = new oxField();
00536 $oDiscount->oxdiscount__oxitmmultiple = new oxField();
00537
00538 return $oDiscount;
00539 }
00540
00548 protected function _getBasketItems($oDiscount = null)
00549 {
00550 if ($this->oxvouchers__oxorderid->value) {
00551 return $this->_getOrderBasketItems($oDiscount);
00552 } elseif ( $this->getSession()->getBasket() ) {
00553 return $this->_getSessionBasketItems($oDiscount);
00554 } else {
00555 return array();
00556 }
00557 }
00558
00566 protected function _getOrderBasketItems($oDiscount = null)
00567 {
00568 if (is_null($oDiscount)) {
00569 $oDiscount = $this->_getSerieDiscount();
00570 }
00571
00572 $oOrder = oxNew('oxorder');
00573 $oOrder->load($this->oxvouchers__oxorderid->value);
00574
00575 $aItems = array();
00576 $iCount = 0;
00577
00578 foreach ( $oOrder->getOrderArticles(true) as $oOrderArticle ) {
00579 if (!$oOrderArticle->skipDiscounts() && $oDiscount->isForBasketItem($oOrderArticle)) {
00580 $aItems[$iCount] = array(
00581 'oxid' => $oOrderArticle->getProductId(),
00582 'price' => $oOrderArticle->oxorderarticles__oxprice->value,
00583 'discount' => $oDiscount->getAbsValue($oOrderArticle->oxorderarticles__oxprice->value),
00584 'amount' => $oOrderArticle->oxorderarticles__oxamount->value,
00585 );
00586 $iCount ++;
00587 }
00588 }
00589
00590 return $aItems;
00591 }
00592
00600 protected function _getSessionBasketItems($oDiscount = null)
00601 {
00602 if (is_null($oDiscount)) {
00603 $oDiscount = $this->_getSerieDiscount();
00604 }
00605
00606 $oBasket = $this->getSession()->getBasket();
00607 $aItems = array();
00608 $iCount = 0;
00609
00610 foreach ( $oBasket->getContents() as $oBasketItem ) {
00611 if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle() ) && !$oArticle->skipDiscounts() && $oDiscount->isForBasketItem($oArticle) ) {
00612
00613 $aItems[$iCount] = array(
00614 'oxid' => $oArticle->getId(),
00615 'price' => $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice(),
00616 'discount' => $oDiscount->getAbsValue($oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice()),
00617 'amount' => $oBasketItem->getAmount(),
00618 );
00619
00620 $iCount ++;
00621 }
00622 }
00623
00624 return $aItems;
00625 }
00626
00636 protected function _getGenericDiscoutValue( $dPrice )
00637 {
00638 $oSerie = $this->getSerie();
00639 if ( $oSerie->oxvoucherseries__oxdiscounttype->value == 'absolute' ) {
00640 $oCur = $this->getConfig()->getActShopCurrencyObject();
00641 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value * $oCur->rate;
00642 } else {
00643 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value / 100 * $dPrice;
00644 }
00645
00646 if ( $dDiscount > $dPrice ) {
00647 $dDiscount = $dPrice;
00648 }
00649
00650 return $dDiscount;
00651 }
00652
00662 protected function _getProductDiscoutValue( $dPrice )
00663 {
00664 $oDiscount = $this->_getSerieDiscount();
00665 $aBasketItems = $this->_getBasketItems($oDiscount);
00666
00667
00668 if (!count($aBasketItems) && !$this->isAdmin() ) {
00669 $oEx = oxNew( 'oxVoucherException' );
00670 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00671 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00672 throw $oEx;
00673 }
00674
00675 $oSerie = $this->getSerie();
00676
00677 $oVoucherPrice = oxNew('oxPrice');
00678 $oDiscountPrice = oxNew('oxPrice');
00679 $oProductPrice = oxNew('oxPrice');
00680 $oProductTotal = oxNew('oxPrice');
00681
00682 foreach ( $aBasketItems as $aBasketItem ) {
00683
00684 $oDiscountPrice->setPrice($aBasketItem['discount']);
00685 $oProductPrice->setPrice($aBasketItem['price']);
00686
00687
00688 if (!$oSerie->oxvoucherseries__oxcalculateonce->value) {
00689 $oDiscountPrice->multiply($aBasketItem['amount']);
00690 $oProductPrice->multiply($aBasketItem['amount']);
00691 }
00692
00693 $oVoucherPrice->add($oDiscountPrice->getBruttoPrice());
00694 $oProductTotal->add($oProductPrice->getBruttoPrice());
00695 }
00696
00697 $dVoucher = $oVoucherPrice->getBruttoPrice();
00698 $dProduct = $oProductTotal->getBruttoPrice();
00699
00700 if ( $dVoucher > $dProduct ) {
00701 return $dProduct;
00702 }
00703
00704 return $dVoucher;
00705 }
00706
00716 protected function _getCategoryDiscoutValue( $dPrice )
00717 {
00718 $oDiscount = $this->_getSerieDiscount();
00719 $aBasketItems = $this->_getBasketItems( $oDiscount );
00720
00721
00722 if ( !count( $aBasketItems ) && !$this->isAdmin() ) {
00723 $oEx = oxNew( 'oxVoucherException' );
00724 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00725 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00726 throw $oEx;
00727 }
00728
00729 $oProductPrice = oxNew('oxPrice');
00730 $oProductTotal = oxNew('oxPrice');
00731
00732 foreach ( $aBasketItems as $aBasketItem ) {
00733 $oProductPrice->setPrice( $aBasketItem['price'] );
00734 $oProductPrice->multiply( $aBasketItem['amount'] );
00735 $oProductTotal->add( $oProductPrice->getBruttoPrice() );
00736 }
00737
00738 $dProduct = $oProductTotal->getBruttoPrice();
00739 $dVoucher = $oDiscount->getAbsValue( $dProduct );
00740 return ( $dVoucher > $dProduct ) ? $dProduct : $dVoucher;
00741 }
00742
00750 public function __get( $sName )
00751 {
00752 switch ( $sName ) {
00753
00754
00755 case 'sVoucherId':
00756 return $this->getId();
00757 break;
00758 case 'sVoucherNr':
00759 return $this->oxvouchers__oxvouchernr;
00760 break;
00761 case 'fVoucherdiscount':
00762 return $this->oxvouchers__oxdiscount;
00763 break;
00764 }
00765 return parent::__get($sName);
00766 }
00767 }