|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZMultiPrice class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package kernel 00009 */ 00010 00011 /*! 00012 \class eZMultiPrice ezmultiprice.php 00013 \ingroup eZDatatype 00014 \brief Handles prices in different currencies with VAT and discounts. 00015 00016 The available attributes are: 00017 - vat_type 00018 - current_user 00019 - is_vat_included 00020 - selected_vat_type 00021 - vat_percent 00022 - inc_vat_price 00023 - ex_vat_price 00024 - discount_percent 00025 - discount_price_inc_vat 00026 - discount_price_ex_vat 00027 - has_discount 00028 - price 00029 */ 00030 00031 class eZMultiPrice extends eZSimplePrice 00032 { 00033 const CALCULATION_TYPE_VAT_INCLUDE = 1; 00034 const CALCULATION_TYPE_VAT_EXCLUDE = 2; 00035 const CALCULATION_TYPE_DISCOUNT_INCLUDE = 3; 00036 const CALCULATION_TYPE_DISCOUNT_EXCLUDE = 4; 00037 00038 /*! 00039 Constructor 00040 */ 00041 function eZMultiPrice( $classAttribute, $contentObjectAttribute, $storedPrice = null ) 00042 { 00043 eZSimplePrice::eZSimplePrice( $classAttribute, $contentObjectAttribute, $storedPrice ); 00044 00045 $isVatIncluded = ( $classAttribute->attribute( eZMultiPriceType::INCLUDE_VAT_FIELD ) == 1 ); 00046 $VATID = $classAttribute->attribute( eZMultiPriceType::VAT_ID_FIELD ); 00047 00048 $this->setVatIncluded( $isVatIncluded ); 00049 $this->setVatType( $VATID ); 00050 00051 $this->IsDataDirty = false; 00052 $this->ContentObjectAttribute = $contentObjectAttribute; 00053 } 00054 00055 /*! 00056 \return An array with attributes that is available. 00057 */ 00058 function attributes() 00059 { 00060 return array_unique( array_merge( array( 'currency_list', 00061 'auto_currency_list', 00062 'price_list', 00063 'auto_price_list', 00064 'custom_price_list', 00065 'inc_vat_price_list', 00066 'ex_vat_price_list', 00067 'discount_inc_vat_price_list', 00068 'discount_ex_vat_price_list' ), 00069 eZSimplePrice::attributes() ) ); 00070 } 00071 00072 /*! 00073 \return \c true if the attribute named \a $attr exists. 00074 */ 00075 function hasAttribute( $attr ) 00076 { 00077 return in_array( $attr, $this->attributes() ); 00078 } 00079 00080 /*! 00081 Sets the attribute named \a $attr to value \a $value. 00082 */ 00083 function setAttribute( $attr, $value ) 00084 { 00085 switch ( $attr ) 00086 { 00087 case 'currency_list': 00088 { 00089 } break; 00090 00091 case 'auto_currency_list': 00092 { 00093 } break; 00094 00095 case 'price_list': 00096 { 00097 } break; 00098 00099 case 'auto_price_list': 00100 { 00101 } break; 00102 00103 case 'custom_price_list': 00104 { 00105 } break; 00106 00107 default: 00108 { 00109 eZSimplePrice::setAttribute( $attr, $value ); 00110 } break; 00111 } 00112 } 00113 00114 /*! 00115 \return The value of the attribute named \a $attr or \c null if it doesn't exist. 00116 */ 00117 function attribute( $attr ) 00118 { 00119 switch ( $attr ) 00120 { 00121 case 'currency_list': 00122 { 00123 return $this->currencyList(); 00124 } break; 00125 00126 case 'auto_currency_list': 00127 { 00128 return $this->autoCurrencyList(); 00129 } break; 00130 00131 case 'price_list': 00132 { 00133 return $this->priceList(); 00134 } break; 00135 00136 case 'inc_vat_price_list': 00137 { 00138 return $this->incVATPriceList(); 00139 } break; 00140 00141 case 'ex_vat_price_list': 00142 { 00143 return $this->exVATPriceList(); 00144 } break; 00145 00146 case 'discount_inc_vat_price_list': 00147 { 00148 return $this->discountIncVATPriceList(); 00149 } break; 00150 00151 case 'discount_ex_vat_price_list': 00152 { 00153 return $this->discountExVATPriceList(); 00154 } break; 00155 00156 case 'auto_price_list': 00157 { 00158 return $this->autoPriceList(); 00159 } break; 00160 00161 case 'custom_price_list': 00162 { 00163 return $this->customPriceList(); 00164 } break; 00165 00166 default : 00167 { 00168 return eZSimplePrice::attribute( $attr ); 00169 } break; 00170 } 00171 } 00172 00173 /*! 00174 functional attribute 00175 */ 00176 00177 function preferredCurrencyCode() 00178 { 00179 return eZShopFunctions::preferredCurrencyCode(); 00180 } 00181 00182 function currencyList() 00183 { 00184 if ( !isset( $this->CurrencyList ) ) 00185 { 00186 $this->CurrencyList = eZCurrencyData::fetchList(); 00187 } 00188 00189 return $this->CurrencyList; 00190 } 00191 00192 /*! 00193 functional attribute 00194 */ 00195 function autoCurrencyList() 00196 { 00197 // 'auto currencies' are the currencies used for 'auto' prices. 00198 // 'auto currencies' = 'all currencies' - 'currencies of custom prices' 00199 00200 $autoCurrecyList = $this->currencyList(); 00201 $customPriceList = $this->customPriceList(); 00202 foreach ( $customPriceList as $price ) 00203 { 00204 if ( $price ) 00205 { 00206 $currencyCode = $price->attribute( 'currency_code' ); 00207 unset( $autoCurrecyList[$currencyCode] ); 00208 } 00209 } 00210 00211 return $autoCurrecyList; 00212 } 00213 00214 /*! 00215 functional attribute 00216 */ 00217 function customPriceList() 00218 { 00219 return $this->priceList( eZMultiPriceData::VALUE_TYPE_CUSTOM ); 00220 } 00221 00222 function autoPriceList() 00223 { 00224 return $this->priceList( eZMultiPriceData::VALUE_TYPE_AUTO ); 00225 } 00226 00227 function priceList( $type = false ) 00228 { 00229 if ( !isset( $this->PriceList ) ) 00230 { 00231 if ( is_object( $this->ContentObjectAttribute ) ) 00232 { 00233 $this->PriceList = eZMultiPriceData::fetch( $this->ContentObjectAttribute->attribute( 'id' ), 00234 $this->ContentObjectAttribute->attribute( 'version' ) ); 00235 } 00236 00237 if ( !$this->PriceList ) 00238 { 00239 $this->PriceList = array(); 00240 } 00241 } 00242 00243 $priceList = array(); 00244 if ( $type !== false ) 00245 { 00246 foreach ( $this->priceList() as $currencyCode => $price ) 00247 { 00248 if ( $price->attribute( 'type' ) == $type ) 00249 { 00250 $priceList[$currencyCode] = $price; 00251 } 00252 } 00253 } 00254 else 00255 { 00256 $priceList = $this->PriceList; 00257 } 00258 00259 return $priceList; 00260 } 00261 00262 function incVATPriceList( $type = false ) 00263 { 00264 return $this->calcPriceList( self::CALCULATION_TYPE_VAT_INCLUDE, $type ); 00265 } 00266 00267 function exVATPriceList( $type = false ) 00268 { 00269 return $this->calcPriceList( self::CALCULATION_TYPE_VAT_EXCLUDE, $type ); 00270 } 00271 00272 function discountIncVATPriceList( $type = false ) 00273 { 00274 return $this->calcPriceList( self::CALCULATION_TYPE_DISCOUNT_INCLUDE, $type ); 00275 } 00276 00277 function discountExVATPriceList( $type = false ) 00278 { 00279 return $this->calcPriceList( self::CALCULATION_TYPE_DISCOUNT_EXCLUDE, $type ); 00280 } 00281 00282 function calcPriceList( $calculationType, $priceType ) 00283 { 00284 $priceList = $this->priceList( $priceType ); 00285 00286 $calculatedPriceList = array(); 00287 foreach ( $priceList as $key => $price ) 00288 { 00289 switch ( $calculationType ) 00290 { 00291 case self::CALCULATION_TYPE_VAT_INCLUDE : 00292 { 00293 $value = $this->calcIncVATPrice( $price->attribute( 'value' ) ); 00294 } break; 00295 00296 case self::CALCULATION_TYPE_VAT_EXCLUDE : 00297 { 00298 $value = $this->calcExVATPrice( $price->attribute( 'value' ) ); 00299 } break; 00300 00301 case self::CALCULATION_TYPE_DISCOUNT_INCLUDE : 00302 { 00303 $value = $this->calcDiscountIncVATPrice( $price->attribute( 'value' ) ); 00304 } break; 00305 00306 case self::CALCULATION_TYPE_DISCOUNT_EXCLUDE : 00307 { 00308 $value = $this->calcDiscountExVATPrice( $price->attribute( 'value' ) ); 00309 } break; 00310 00311 default: 00312 { 00313 // do nothing 00314 } break; 00315 } 00316 00317 $calculatedPrice = clone $price; 00318 $calculatedPrice->setAttribute( 'value', $value ); 00319 $calculatedPriceList[$key] = $calculatedPrice; 00320 } 00321 00322 return $calculatedPriceList; 00323 } 00324 00325 static function removeByID( $objectAttributeID, $objectAttributeVersion = null ) 00326 { 00327 eZMultiPriceData::removeByOAID( $objectAttributeID, $objectAttributeVersion ); 00328 } 00329 00330 function removePriceByCurrency( $currencyCode ) 00331 { 00332 $price = $this->priceByCurrency( $currencyCode ); 00333 if ( $price ) 00334 { 00335 $price->remove(); 00336 $priceList = $this->priceList(); 00337 unset( $priceList[$currencyCode] ); 00338 } 00339 } 00340 00341 function setCustomPrice( $currencyCode, $value ) 00342 { 00343 $this->setPriceByCurrency( $currencyCode, $value, eZMultiPriceData::VALUE_TYPE_CUSTOM ); 00344 } 00345 00346 function setAutoPrice( $currencyCode, $value ) 00347 { 00348 $this->setPriceByCurrency( $currencyCode, $value, eZMultiPriceData::VALUE_TYPE_AUTO ); 00349 } 00350 00351 function setPriceByCurrency( $currencyCode, $value, $type ) 00352 { 00353 if ( !$this->updatePrice( $currencyCode, $value, $type ) && 00354 !$this->addPrice( $currencyCode, $value, $type ) ) 00355 { 00356 eZDebug::writeWarning( "Unable to set price in '$currencyCode'", __METHOD__ ); 00357 return false; 00358 } 00359 00360 return true; 00361 } 00362 00363 function setPrice( $value ) 00364 { 00365 } 00366 00367 function updateAutoPriceList() 00368 { 00369 $converter = eZCurrencyConverter::instance(); 00370 00371 $basePrice = $this->basePrice(); 00372 $basePriceValue = $basePrice ? $basePrice->attribute( 'value' ) : 0; 00373 $baseCurrencyCode = $basePrice ? $basePrice->attribute( 'currency_code' ) : false; 00374 00375 $autoCurrencyList = $this->autoCurrencyList(); 00376 foreach( $autoCurrencyList as $currencyCode => $currency ) 00377 { 00378 $autoValue = $converter->convert( $baseCurrencyCode, $currencyCode, $basePriceValue ); 00379 $this->setAutoPrice( $currencyCode, $autoValue ); 00380 } 00381 } 00382 00383 function createPrice( $currencyCode, $value, $type ) 00384 { 00385 if ( is_object( $this->ContentObjectAttribute ) && $this->currencyByCode( $currencyCode ) ) 00386 { 00387 return eZMultiPriceData::create( $this->ContentObjectAttribute->attribute( 'id' ), 00388 $this->ContentObjectAttribute->attribute( 'version' ), 00389 $currencyCode, 00390 $value, 00391 $type ); 00392 } 00393 return false; 00394 } 00395 00396 00397 function addPrice( $currencyCode, $value, $type ) 00398 { 00399 $price = $this->createPrice( $currencyCode, $value, $type ); 00400 if( $price ) 00401 { 00402 if ( $value === false ) 00403 $price->setAttribute( 'value', '0.00' ); 00404 00405 $this->PriceList[$price->attribute( 'currency_code' )] = $price; 00406 $this->setHasDirtyData( true ); 00407 } 00408 00409 return $price; 00410 } 00411 00412 function updatePrice( $currencyCode, $value, $type ) 00413 { 00414 $price = $this->priceByCurrency( $currencyCode ); 00415 if( $price ) 00416 { 00417 if ( $value !== false ) 00418 { 00419 $price->setAttribute( 'value', $value ); 00420 } 00421 00422 if ( $type !== false ) 00423 { 00424 $price->setAttribute( 'type', $type ); 00425 } 00426 00427 $this->setHasDirtyData( true ); 00428 } 00429 00430 return $price; 00431 } 00432 00433 function customPrice( $currencyCode ) 00434 { 00435 return $this->priceByCurrency( $currencyCode, eZMultiPriceData::VALUE_TYPE_CUSTOM ); 00436 } 00437 00438 function autoPrice( $currencyCode ) 00439 { 00440 return $this->priceByCurrency( $currencyCode, eZMultiPriceData::VALUE_TYPE_AUTO ); 00441 } 00442 00443 function priceByCurrency( $currencyCode, $type = false ) 00444 { 00445 $price = false; 00446 $priceList = $this->priceList(); 00447 00448 if ( isset( $priceList[$currencyCode] ) ) 00449 { 00450 if( $type === false || $priceList[$currencyCode]->attribute( 'type' ) == $type ) 00451 { 00452 $price = $priceList[$currencyCode]; 00453 } 00454 } 00455 00456 return $price; 00457 } 00458 00459 function price() 00460 { 00461 $value = '0.0'; 00462 if ( $currencyCode = $this->preferredCurrencyCode() ) 00463 { 00464 $price = $this->priceByCurrency( $currencyCode ); 00465 if ( $price ) 00466 { 00467 $value = $price->attribute( 'value' ); 00468 } 00469 } 00470 00471 return $value; 00472 } 00473 00474 function currencyByCode( $currencyCode ) 00475 { 00476 $currency = false; 00477 $currencyList = $this->currencyList(); 00478 if ( isset( $currencyList[$currencyCode] ) ) 00479 { 00480 $currency = $currencyList[$currencyCode]; 00481 } 00482 00483 return $currency; 00484 } 00485 00486 function store() 00487 { 00488 if ( $this->hasDirtyData() ) 00489 { 00490 $this->storePriceList(); 00491 $this->setHasDirtyData( false ); 00492 } 00493 } 00494 00495 function storePriceList() 00496 { 00497 if ( isset( $this->PriceList ) && count( $this->PriceList ) > 0 ) 00498 { 00499 $priceList = $this->priceList(); 00500 foreach ( $priceList as $price ) 00501 { 00502 $price->store(); 00503 } 00504 } 00505 } 00506 00507 function hasDirtyData() 00508 { 00509 return $this->HasDataDirty; 00510 } 00511 00512 function setHasDirtyData( $hasDirtyData ) 00513 { 00514 $this->HasDataDirty = $hasDirtyData; 00515 } 00516 00517 /*! 00518 Returns a currency code of the first custom price. 00519 */ 00520 function baseCurrency() 00521 { 00522 // use value of the first custom price as 00523 // base price and base currency. 00524 00525 $baseCurrency = false; 00526 $customPriceList = $this->customPriceList(); 00527 $currencies = array_keys( $customPriceList ); 00528 if ( count( $currencies ) > 0 ) 00529 { 00530 $baseCurrency = $currencies[0]; 00531 } 00532 00533 return $baseCurrency; 00534 } 00535 00536 function basePrice() 00537 { 00538 $baseCurrencyCode = $this->baseCurrency(); 00539 return $this->priceByCurrency( $baseCurrencyCode ); 00540 } 00541 00542 function currency() 00543 { 00544 return $this->preferredCurrencyCode(); 00545 } 00546 00547 function DOMDocument() 00548 { 00549 $doc = new DOMDocument( '1.0', 'utf-8' ); 00550 $root = $doc->createElement( 'ezmultiprice' ); 00551 $doc->appendChild( $root ); 00552 00553 $priceListNode = $doc->createElement( 'price-list' ); 00554 00555 $priceList = $this->attribute( 'price_list' ); 00556 foreach ( $priceList as $price ) 00557 { 00558 $currencyCode = $price->attribute( 'currency_code' ); 00559 $value = $price->attribute( 'value' ); 00560 $type = $price->attribute( 'type' ); 00561 00562 $priceNode = $doc->createElement( 'price' ); 00563 00564 $priceNode->setAttribute( 'currency-code', $currencyCode ); 00565 $priceNode->setAttribute( 'value', $value ); 00566 $priceNode->setAttribute( 'type', $type ); 00567 00568 $priceListNode->appendChild( $priceNode ); 00569 unset( $priceNode ); 00570 } 00571 00572 $root->appendChild( $priceListNode ); 00573 00574 return $doc; 00575 } 00576 00577 function decodeDOMTree( $rootNode ) 00578 { 00579 $priceNode = $rootNode->getElementsByTagName( 'price-list' )->item( 0 ); 00580 $priceNodes = $priceNode->getElementsByTagName( 'price' ); 00581 if ( $priceNodes->length > 0 ) 00582 { 00583 foreach ( $priceNodes as $priceNode ) 00584 { 00585 $currencyCode = $priceNode->getAttribute( 'currency-code' ); 00586 $value = $priceNode->getAttribute( 'value' ); 00587 $type = $priceNode->getAttribute( 'type' ); 00588 00589 $this->setPriceByCurrency( $currencyCode, $value, $type ); 00590 } 00591 } 00592 } 00593 00594 /// \privatesection 00595 public $PriceList; 00596 public $CurrencyList; 00597 public $HasDataDirty; 00598 public $ContentObjectAttribute; 00599 } 00600 00601 ?>