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 throw $oEx;
00257 }
00258 }
00259 }
00260 }
00261
00262 return true;
00263 }
00264
00275 protected function _isAvailableWithOtherSeries( $aVouchers )
00276 {
00277 if ( is_array( $aVouchers ) && count($aVouchers) ) {
00278 $oSerie = $this->getSerie();
00279 $sIds = '\''.implode('\',\'', array_keys($aVouchers)).'\'';
00280 $blAvailable = true;
00281 if (!$oSerie->oxvoucherseries__oxallowotherseries->value) {
00282
00283 $sSql = "select 1 from oxvouchers where oxvouchers.oxid in ($sIds) and ";
00284 $sSql .= "oxvouchers.oxvoucherserieid != " . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value ) ;
00285 $blAvailable &= !oxDb::getDb()->getOne($sSql);
00286 } else {
00287
00288 $sSql = "select 1 from oxvouchers left join oxvoucherseries on oxvouchers.oxvoucherserieid=oxvoucherseries.oxid ";
00289 $sSql .= "where oxvouchers.oxid in ($sIds) and oxvouchers.oxvoucherserieid != " . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value );
00290 $sSql .= "and not oxvoucherseries.oxallowotherseries";
00291 $blAvailable &= !oxDb::getDb()->getOne($sSql);
00292 }
00293 if ( !$blAvailable ) {
00294 $oEx = oxNew( 'oxVoucherException' );
00295 $oEx->setMessage('EXCEPTION_VOUCHER_NOTALLOWEDOTHERSERIES');
00296 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00297 throw $oEx;
00298 }
00299 }
00300
00301 return true;
00302 }
00303
00311 protected function _isValidDate()
00312 {
00313 $oSerie = $this->getSerie();
00314
00315 $sDefTimeStamp = oxUtilsDate::getInstance()->formatDBDate( '-' );
00316 if ( $oSerie->oxvoucherseries__oxbegindate->value == $sDefTimeStamp &&
00317 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00318 return true;
00319 }
00320
00321 if ( ( strtotime( $oSerie->oxvoucherseries__oxbegindate->value ) < time() &&
00322 strtotime( $oSerie->oxvoucherseries__oxenddate->value ) > time() ) ||
00323 !$oSerie->oxvoucherseries__oxenddate->value ||
00324 $oSerie->oxvoucherseries__oxenddate->value == $sDefTimeStamp ) {
00325 return true;
00326 }
00327
00328 $oEx = oxNew( 'oxVoucherException' );
00329 $oEx->setMessage('EXCEPTION_VOUCHER_ISNOTVALIDDATE');
00330 throw $oEx;
00331 }
00332
00340 protected function _isNotReserved()
00341 {
00342
00343 if ( $this->oxvouchers__oxreserved->value < time() - 3600 * 3 ) {
00344 return true;
00345 }
00346
00347 $oEx = oxNew( 'oxVoucherException' );
00348 $oEx->setMessage('EXCEPTION_VOUCHER_ISRESERVED');
00349 throw $oEx;
00350 }
00351
00352
00362 public function checkUserAvailability( $oUser )
00363 {
00364
00365 $this->_isAvailableInOtherOrder( $oUser );
00366 $this->_isValidUserGroup( $oUser );
00367
00368
00369 return true;
00370 }
00371
00381 protected function _isAvailableInOtherOrder( $oUser )
00382 {
00383 $oSerie = $this->getSerie();
00384 if ( !$oSerie->oxvoucherseries__oxallowuseanother->value ) {
00385
00386 $sSelect = 'select count(*) from '.$this->getViewName().' where oxuserid = '. oxDb::getDb()->quote( $oUser->oxuser__oxid->value ) . ' and ';
00387 $sSelect .= 'oxvoucherserieid = ' . oxDb::getDb()->quote( $this->oxvouchers__oxvoucherserieid->value ) . ' and ';
00388 $sSelect .= 'oxorderid is not NULL and oxorderid != "" ';
00389
00390 if ( oxDb::getDb()->getOne( $sSelect )) {
00391 $oEx = oxNew( 'oxVoucherException' );
00392 $oEx->setMessage('EXCEPTION_VOUCHER_NOTAVAILABLEINOTHERORDER');
00393 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00394 throw $oEx;
00395 }
00396 }
00397
00398 return true;
00399 }
00400
00410 protected function _isValidUserGroup( $oUser )
00411 {
00412 $oVoucherSerie = $this->getSerie();
00413 $oUserGroups = $oVoucherSerie->setUserGroups();
00414
00415
00416 if ( !$oUserGroups->count() ) {
00417 return true;
00418 }
00419
00420 if ( $oUser ) {
00421 foreach ( $oUserGroups as $oGroup ) {
00422 if ( $oUser->inGroup( $oGroup->getId() ) ) {
00423 return true;
00424 }
00425 }
00426 }
00427
00428 $oEx = oxNew( 'oxVoucherException' );
00429 $oEx->setMessage( 'EXCEPTION_VOUCHER_NOTVALIDUSERGROUP' );
00430 $oEx->setVoucherNr( $this->oxvouchers__oxvouchernr->value );
00431 throw $oEx;
00432 }
00433
00439 public function getSimpleVoucher()
00440 {
00441 $oVoucher = new oxStdClass();
00442 $oVoucher->sVoucherId = $this->getId();
00443 $oVoucher->sVoucherNr = $this->oxvouchers__oxvouchernr->value;
00444
00445
00446 return $oVoucher;
00447 }
00448
00454 public function getSerie()
00455 {
00456 if ($this->_oSerie !== null) {
00457 return $this->_oSerie;
00458 }
00459 $oSerie = oxNew('oxvoucherserie');
00460 if (!$oSerie->load($this->oxvouchers__oxvoucherserieid->value)) {
00461 throw new oxObjectException();
00462 }
00463 $this->_oSerie = $oSerie;
00464 return $oSerie;
00465 }
00466
00472 protected function _isProductVoucher()
00473 {
00474 $myDB = oxDb::getDb();
00475 $oSerie = $this->getSerie();
00476 $sSelect = "select 1 from oxobject2discount where oxdiscountid = '".$oSerie->getId()."' and oxtype = 'oxarticles'";
00477 $blOk = ( bool ) $myDB->getOne( $sSelect );
00478
00479 return $blOk;
00480 }
00481
00487 protected function _isCategoryVoucher()
00488 {
00489 $myDB = oxDb::getDb();
00490 $oSerie = $this->getSerie();
00491 $sSelect = "select 1 from oxobject2discount where oxdiscountid = '".$oSerie->getId()."' and oxtype = 'oxcategories'";
00492 $blOk = ( bool ) $myDB->getOne( $sSelect );
00493
00494 return $blOk;
00495 }
00496
00502 protected function _getSerieDiscount( )
00503 {
00504 $oSerie = $this->getSerie();
00505 $oDiscount = oxNew('oxDiscount');
00506
00507 $oDiscount->setId($oSerie->getId());
00508 $oDiscount->oxdiscount__oxshopid = new oxField($oSerie->oxvoucherseries__oxshopid->value);
00509 $oDiscount->oxdiscount__oxactive = new oxField(true);
00510 $oDiscount->oxdiscount__oxactivefrom = new oxField($oSerie->oxvoucherseries__oxbegindate->value);
00511 $oDiscount->oxdiscount__oxactiveto = new oxField($oSerie->oxvoucherseries__oxenddate->value);
00512 $oDiscount->oxdiscount__oxtitle = new oxField($oSerie->oxvoucherseries__oxserienr->value);
00513 $oDiscount->oxdiscount__oxamount = new oxField(1);
00514 $oDiscount->oxdiscount__oxamountto = new oxField(MAX_64BIT_INTEGER);
00515 $oDiscount->oxdiscount__oxprice = new oxField(0);
00516 $oDiscount->oxdiscount__oxpriceto = new oxField(MAX_64BIT_INTEGER);
00517 $oDiscount->oxdiscount__oxaddsumtype = new oxField($oSerie->oxvoucherseries__oxdiscounttype->value=='percent'?'%':'abs');
00518 $oDiscount->oxdiscount__oxaddsum = new oxField($oSerie->oxvoucherseries__oxdiscount->value);
00519 $oDiscount->oxdiscount__oxitmartid = new oxField();
00520 $oDiscount->oxdiscount__oxitmamount = new oxField();
00521 $oDiscount->oxdiscount__oxitmmultiple = new oxField();
00522
00523 return $oDiscount;
00524 }
00525
00533 protected function _getBasketItems($oDiscount = null)
00534 {
00535 if ($this->oxvouchers__oxorderid->value) {
00536 return $this->_getOrderBasketItems($oDiscount);
00537 } elseif ( $this->getSession()->getBasket() ) {
00538 return $this->_getSessionBasketItems($oDiscount);
00539 } else {
00540 return array();
00541 }
00542 }
00543
00551 protected function _getOrderBasketItems($oDiscount = null)
00552 {
00553 if (is_null($oDiscount)) {
00554 $oDiscount = $this->_getSerieDiscount();
00555 }
00556
00557 $oOrder = oxNew('oxorder');
00558 $oOrder->load($this->oxvouchers__oxorderid->value);
00559
00560 $aItems = array();
00561 $iCount = 0;
00562
00563 foreach ( $oOrder->getOrderArticles(true) as $oOrderArticle ) {
00564 if (!$oOrderArticle->skipDiscounts() && $oDiscount->isForBasketItem($oOrderArticle)) {
00565 $aItems[$iCount] = array(
00566 'oxid' => $oOrderArticle->getProductId(),
00567 'price' => $oOrderArticle->oxorderarticles__oxprice->value,
00568 'discount' => $oDiscount->getAbsValue($oOrderArticle->oxorderarticles__oxprice->value),
00569 'amount' => $oOrderArticle->oxorderarticles__oxamount->value,
00570 );
00571 $iCount ++;
00572 }
00573 }
00574
00575 return $aItems;
00576 }
00577
00585 protected function _getSessionBasketItems($oDiscount = null)
00586 {
00587 if (is_null($oDiscount)) {
00588 $oDiscount = $this->_getSerieDiscount();
00589 }
00590
00591 $oBasket = $this->getSession()->getBasket();
00592 $aItems = array();
00593 $iCount = 0;
00594
00595 foreach ( $oBasket->getContents() as $oBasketItem ) {
00596 if ( !$oBasketItem->isDiscountArticle() && ( $oArticle = $oBasketItem->getArticle() ) && !$oArticle->skipDiscounts() && $oDiscount->isForBasketItem($oArticle) ) {
00597
00598 $aItems[$iCount] = array(
00599 'oxid' => $oArticle->getId(),
00600 'price' => $oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice(),
00601 'discount' => $oDiscount->getAbsValue($oArticle->getBasketPrice( $oBasketItem->getAmount(), $oBasketItem->getSelList(), $oBasket )->getBruttoPrice()),
00602 'amount' => $oBasketItem->getAmount(),
00603 );
00604
00605 $iCount ++;
00606 }
00607 }
00608
00609 return $aItems;
00610 }
00611
00621 protected function _getGenericDiscoutValue( $dPrice )
00622 {
00623 $oSerie = $this->getSerie();
00624 if ( $oSerie->oxvoucherseries__oxdiscounttype->value == 'absolute' ) {
00625 $oCur = $this->getConfig()->getActShopCurrencyObject();
00626 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value * $oCur->rate;
00627 } else {
00628 $dDiscount = $oSerie->oxvoucherseries__oxdiscount->value / 100 * $dPrice;
00629 }
00630
00631 if ( $dDiscount > $dPrice ) {
00632 $oEx = oxNew( 'oxVoucherException' );
00633 $oEx->setMessage('EXCEPTION_VOUCHER_TOTALBELOWZERO');
00634 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00635 throw $oEx;
00636 }
00637
00638 return $dDiscount;
00639 }
00640
00650 protected function _getProductDiscoutValue( $dPrice )
00651 {
00652 $oDiscount = $this->_getSerieDiscount();
00653 $aBasketItems = $this->_getBasketItems($oDiscount);
00654
00655
00656 if (!count($aBasketItems) && !$this->isAdmin() ) {
00657 $oEx = oxNew( 'oxVoucherException' );
00658 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00659 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00660 throw $oEx;
00661 }
00662
00663 $oSerie = $this->getSerie();
00664
00665 $oVoucherPrice = oxNew('oxPrice');
00666 $oDiscountPrice = oxNew('oxPrice');
00667 $oProductPrice = oxNew('oxPrice');
00668 $oProductTotal = oxNew('oxPrice');
00669
00670 foreach ( $aBasketItems as $aBasketItem ) {
00671
00672 $oDiscountPrice->setPrice($aBasketItem['discount']);
00673 $oProductPrice->setPrice($aBasketItem['price']);
00674
00675
00676 if (!$oSerie->oxvoucherseries__oxcalculateonce->value) {
00677 $oDiscountPrice->multiply($aBasketItem['amount']);
00678 $oProductPrice->multiply($aBasketItem['amount']);
00679 }
00680
00681 $oVoucherPrice->add($oDiscountPrice->getBruttoPrice());
00682 $oProductTotal->add($oProductPrice->getBruttoPrice());
00683 }
00684
00685 $dVoucher = $oVoucherPrice->getBruttoPrice();
00686 $dProduct = $oProductTotal->getBruttoPrice();
00687
00688 if ( $dVoucher > $dProduct ) {
00689 return $dProduct;
00690 }
00691
00692 return $dVoucher;
00693 }
00694
00704 protected function _getCategoryDiscoutValue( $dPrice )
00705 {
00706 $oDiscount = $this->_getSerieDiscount();
00707 $aBasketItems = $this->_getBasketItems($oDiscount);
00708
00709
00710 if (!count($aBasketItems) && !$this->isAdmin() ) {
00711 $oEx = oxNew( 'oxVoucherException' );
00712 $oEx->setMessage('EXCEPTION_VOUCHER_NOVOUCHER');
00713 $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
00714 throw $oEx;
00715 }
00716
00717 $oCategoryPrice = oxNew('oxPrice');
00718 $oProductPrice = oxNew('oxPrice');
00719 $oProductTotal = oxNew('oxPrice');
00720
00721 foreach ( $aBasketItems as $aBasketItem ) {
00722
00723 $oProductPrice->setPrice($aBasketItem['price']);
00724 $oProductPrice->multiply($aBasketItem['amount']);
00725
00726 $oCategoryPrice->add($aBasketItem['price']);
00727 $oProductTotal->add($oProductPrice->getBruttoPrice());
00728 }
00729
00730 $dVoucher = $oDiscount->getAbsValue($oCategoryPrice->getBruttoPrice());
00731 $dProduct = $oProductTotal->getBruttoPrice();
00732
00733 if ( $dVoucher > $dProduct ) {
00734 return $dProduct;
00735 }
00736
00737 return $dVoucher;
00738 }
00739
00747 public function __get( $sName )
00748 {
00749 switch ( $sName ) {
00750
00751
00752 case 'sVoucherId':
00753 return $this->getId();
00754 break;
00755 case 'sVoucherNr':
00756 return $this->oxvouchers__oxvouchernr;
00757 break;
00758 case 'fVoucherdiscount':
00759 return $this->oxvouchers__oxdiscount;
00760 break;
00761
00762
00763 case 'oxmodvouchers__oxvouchernr':
00764 return $this->oxvouchers__oxvouchernr;
00765 break;
00766 case 'oxmodvouchers__oxdiscounttype':
00767 return $this->getSerie()->oxvoucherseries__oxdiscounttype;
00768 break;
00769 case 'oxmodvouchers__oxdiscount':
00770
00771 if ($this->getSerie()->oxvoucherseries__oxdiscounttype->value == 'absolute') {
00772 return $this->oxvouchers__oxdiscount;
00773 } else {
00774 return $this->getSerie()->oxvoucherseries__oxdiscount;
00775 }
00776 break;
00777 }
00778 return parent::__get($sName);
00779 }
00780 }