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