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