eZ Publish  [trunk]
ezshippingmanager.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZShippingManager 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 eZShippingManager ezshippingmanager.php
00013   \brief The class eZShippingManager does
00014 */
00015 
00016 class eZShippingManager
00017 {
00018     /*!
00019      \public
00020      \static
00021 
00022      The function are fetching the shipping info and need to be reimplemented in a new shippinghandler.
00023      It's also possible to return additional parameters to use in the templates.
00024 
00025      \return an array with shipping info.
00026      An example for an array that should be returned.
00027 
00028      \code
00029      array( 'shipping_items' => array( array( 'description'     => 'Shipping vat: 12%',
00030                                               'cost'            => 50.25,
00031                                               'vat_value'       => 12,
00032                                               'is_vat_inc'      => 0,
00033                                               'management_link' => '/myshippingmodule/options/12' ),
00034                                        array( 'description'     => 'Shipping vat: 25%',
00035                                               'cost'            => 100.75,
00036                                               'vat_value'       => 25,
00037                                               'is_vat_inc'      => 1,
00038                                               'management_link' => '/myshippingmodule/options/25' ) ),
00039             'description'     => 'Total Shipping',
00040             'cost'            => 10.25,
00041             'vat_value'       => false,
00042             'is_vat_inc'      => 1,
00043             'management_link' => '/myshippingmodule/options' );
00044      \endcode
00045 
00046      An example for the shippingvalues with only one shippingitem.
00047      \code
00048      array( 'description'     => 'Total Shipping vat: 16%',
00049             'cost'            => 10.25,
00050             'vat_value'       => 16,
00051             'is_vat_inc'      => 1,
00052             'management_link' => '/myshippingmodule/options/1234' );
00053      \endcode
00054 
00055      The returned array for each shipping item should consist of these keys:
00056      - description - An own description of the shipping item.
00057      - cost - A float value of the cost for the shipping. The value should be a float value.
00058      - vat_value - The vat value that should be added to the shipping item. The value should be an integer or
00059                    false if the cost is combined by several VAT prices.
00060      - is_vat_inc - Integer, either 0, 1. 0: The cost is excluded VAT.
00061                                           1: the cost is included VAT.
00062 
00063      - management_link - Example of an additional parameter that can be used
00064        in a template. Ex: basket.tpl
00065      */
00066     static function getShippingInfo( $productCollectionID )
00067     {
00068         if ( !is_object( $handler = eZShippingManager::loadShippingHandler() ) )
00069             return null;
00070 
00071         return $handler->getShippingInfo( $productCollectionID );
00072     }
00073 
00074     /*!
00075      \public
00076      \static
00077 
00078      The function to update any additional shippinginfo and need to be reimplemented
00079      in a new shippinghandler.
00080 
00081      \return true if all updates are ok.
00082              false if the update went wrong.
00083      */
00084     static function updateShippingInfo( $productCollectionID )
00085     {
00086         if ( is_object( $handler = eZShippingManager::loadShippingHandler() ) )
00087             return $handler->updateShippingInfo( $productCollectionID );
00088     }
00089 
00090     /*!
00091      Purge shipping information for a stale product collection that is about to be removed.
00092      \public
00093      \static
00094 
00095      Should be used when a basket is removed. All shipping information related to the
00096      productCollectionID should be removed.
00097 
00098 
00099      \return true if everything went ok.
00100              false if an error occurred.
00101      */
00102     static function purgeShippingInfo( $productCollectionID )
00103     {
00104         if ( is_object( $handler = eZShippingManager::loadShippingHandler() ) )
00105             return $handler->purgeShippingInfo( $productCollectionID );
00106     }
00107 
00108     /*!
00109      Load shipping handler (if specified).
00110 
00111      \private
00112      \static
00113      \return true if no handler specified,
00114              false if a handler specified but could not be loaded,
00115              handler object if handler specified and found.
00116      */
00117     static function loadShippingHandler()
00118     {
00119         $shopINI = eZINI::instance( 'shop.ini' );
00120 
00121         if ( !$shopINI->hasVariable( 'ShippingSettings', 'Handler' ) )
00122             return true;
00123 
00124         $handlerName = $shopINI->variable( 'ShippingSettings', 'Handler' );
00125         $repositoryDirectories = $shopINI->variable( 'ShippingSettings', 'RepositoryDirectories' );
00126         $extensionDirectories = $shopINI->variable( 'ShippingSettings', 'ExtensionDirectories' );
00127 
00128         $baseDirectory = eZExtension::baseDirectory();
00129         foreach ( $extensionDirectories as $extensionDirectory )
00130         {
00131             $extensionPath = $baseDirectory . '/' . $extensionDirectory . '/shippinghandlers';
00132             if ( file_exists( $extensionPath ) )
00133                 $repositoryDirectories[] = $extensionPath;
00134         }
00135 
00136         $foundHandler = false;
00137         foreach ( $repositoryDirectories as $repositoryDirectory )
00138         {
00139             $includeFile = "$repositoryDirectory/{$handlerName}shippinghandler.php";
00140 
00141             if ( file_exists( $includeFile ) )
00142             {
00143                 $foundHandler = true;
00144                 break;
00145             }
00146         }
00147 
00148         if ( !$foundHandler )
00149         {
00150             eZDebug::writeError( "Shipping handler '$handlerName' not found, " .
00151                                    "searched in these directories: " .
00152                                    implode( ', ', $repositoryDirectories ),
00153                                  'eZShippingManager::loadShippingHandler' );
00154             return false;
00155         }
00156 
00157         require_once( $includeFile );
00158         $className = $handlerName . 'ShippingHandler';
00159         if ( !class_exists ( $className ) )
00160         {
00161             eZDebug::writeError( "Cannot instantiate non-existent class: '$className'", __METHOD__ );
00162             return null;
00163         }
00164 
00165         return new $className;
00166     }
00167 
00168     /*!
00169      Load basketinfo handler (if specified).
00170 
00171      \private
00172      \static
00173      \return true if no handler specified,
00174              false if a handler specified but could not be loaded,
00175              handler object if handler specified and found.
00176      */
00177     static function loadBasketInfoHandler()
00178     {
00179         $shopINI = eZINI::instance( 'shop.ini' );
00180 
00181         if ( !$shopINI->hasVariable( 'BasketInfoSettings', 'Handler' ) )
00182             return true;
00183 
00184         $handlerName = $shopINI->variable( 'BasketInfoSettings', 'Handler' );
00185         $repositoryDirectories = $shopINI->variable( 'BasketInfoSettings', 'RepositoryDirectories' );
00186         $extensionDirectories = $shopINI->variable( 'BasketInfoSettings', 'ExtensionDirectories' );
00187 
00188         $baseDirectory = eZExtension::baseDirectory();
00189         foreach ( $extensionDirectories as $extensionDirectory )
00190         {
00191             $extensionPath = $baseDirectory . '/' . $extensionDirectory . '/basketinfohandlers';
00192             if ( file_exists( $extensionPath ) )
00193                 $repositoryDirectories[] = $extensionPath;
00194         }
00195 
00196         $foundHandler = false;
00197         foreach ( $repositoryDirectories as $repositoryDirectory )
00198         {
00199             $includeFile = "$repositoryDirectory/{$handlerName}basketinfohandler.php";
00200 
00201             if ( file_exists( $includeFile ) )
00202             {
00203                 $foundHandler = true;
00204                 break;
00205             }
00206         }
00207 
00208         if ( !$foundHandler )
00209         {
00210             eZDebug::writeError( "Basketinfo handler '$handlerName' not found, " .
00211                                    "searched in these directories: " .
00212                                    implode( ', ', $repositoryDirectories ),
00213                                  'eZShippingManager::loadBasketInfoHandler' );
00214             return false;
00215         }
00216 
00217         require_once( $includeFile );
00218         $className = $handlerName . 'BasketInfoHandler';
00219         if ( !class_exists ( $className ) )
00220         {
00221             eZDebug::writeError( "Cannot instantiate non-existent class: '$className'", __METHOD__ );
00222             return null;
00223         }
00224 
00225         return new $className;
00226     }
00227 
00228     /*!
00229      Calculate the vat prices returned by the shippinghandler.
00230      \public
00231      \static
00232 
00233      Need to receive the following values (In the arrays will also consist of
00234      additional parameters, see the function getShippingInfo() for more information):
00235 
00236      Option 1: An array with shipping items with atleast these values:
00237      \code
00238      array( 'shipping_items' => array( array( 'cost'       => 50.25,
00239                                               'vat_value'  => 12,
00240                                               'is_vat_inc' => 0 ),
00241                                        array( 'cost'       => 100.75,
00242                                               'vat_value'  => 25,
00243                                               'is_vat_inc' => 1 ) ),
00244             'cost'       => 157.03,
00245             'vat_value'  => false,
00246             'is_vat_inc' => 1 );
00247      \endcode
00248 
00249      Option 2, backwards compatible:
00250      \code
00251      array( 'cost'       => 50.25,
00252             'vat_value'  => 12,
00253             'is_vat_inc' => 0 );
00254      \endcode
00255 
00256      \return array with calculated vat prices.
00257              Example of return value:
00258      \code
00259      array( 'vat_shipping_list_ex_vat'  => array(  5 => 345.25,
00260                                                   25 => 112.50 ),
00261             'vat_shipping_list_inc_vat' => array(  5 => 125,
00262                                                   25 => 150.50 ),
00263             'total_shipping_ex_vat'  => 1234,
00264             'total_shipping_inc_vat' => 2345 );
00265      \endcode
00266 
00267      - vat_shipping_list_ex_vat  - contains an array with prices (float) ex vat
00268                                    where you have the vat (integer) value as the array key.
00269      - vat_shipping_list_inc_vat - contains an array with prices (float) inc vat
00270                                    where you have the vat value (integer) as the array key.
00271      - total_shipping_ex_vat     - contains the sum of all prices (float) ex vat.
00272      - total_shipping_inc_vat    - contains the sum of all prices (float) inc vat.
00273      */
00274     static function vatPriceInfo( $shippingInfo )
00275     {
00276         $totalShippingExVat = 0;
00277         $totalShippingIncVat = 0;
00278         $totalShippingVat = 0;
00279         $subShippingExVat = array();
00280         $subShippingIncVat = array();
00281         $shippingVatList = array();
00282         if ( isset( $shippingInfo['shipping_items'] ) )
00283         {
00284             foreach ( $shippingInfo['shipping_items'] as $shippingItem )
00285             {
00286                 $vatValue = $shippingItem['vat_value'];
00287                 $shippingCost = $shippingItem['cost'];
00288                 $isVatInc = $shippingItem['is_vat_inc'];
00289 
00290                 if ( $isVatInc == 1 )
00291                 {
00292                     $divideValue = ( $vatValue / 100 ) + 1;
00293                     if ( !isset( $subShippingExVat[$vatValue] ) )
00294                     {
00295                         $subShippingExVat[$vatValue] = ( $shippingCost / $divideValue );
00296                         $subShippingIncVat[$vatValue] = $shippingCost;
00297                         $subShippingVat[$vatValue] = ( $shippingCost - ( $shippingCost / $divideValue ) );
00298                     }
00299                     else
00300                     {
00301                         $subShippingExVat[$vatValue] += ( $shippingCost / $divideValue );
00302                         $subShippingIncVat[$vatValue] += $shippingCost;
00303                         $subShippingVat[$vatValue] += ( $shippingCost - ( $shippingCost / $divideValue ) );
00304                     }
00305                 }
00306                 else
00307                 {
00308                     $multiplier = ( $vatValue / 100 ) + 1;
00309                     if ( !isset( $subShippingExVat[$vatValue] ) )
00310                     {
00311                         $subShippingExVat[$vatValue] = $shippingCost;
00312                         $subShippingIncVat[$vatValue] = ( $shippingCost * $multiplier );
00313                         $subShippingVat[$vatValue] = ( ( $shippingCost * $multiplier ) - $shippingCost );
00314                     }
00315                     else
00316                     {
00317                         $subShippingExVat[$vatValue] += $shippingCost;
00318                         $subShippingIncVat[$vatValue] += ( $shippingCost * $multiplier );
00319                         $subShippingVat[$vatValue] += ( ( $shippingCost * $multiplier ) - $shippingCost );
00320                     }
00321                 }
00322 
00323                 if ( !isset( $shippingVatList[$vatValue]['shipping_ex_vat'] ) )
00324                 {
00325                     $shippingVatList[$vatValue]['shipping_ex_vat'] = $subShippingExVat[$vatValue];
00326                     $shippingVatList[$vatValue]['shipping_inc_vat'] = $subShippingIncVat[$vatValue];
00327                     $shippingVatList[$vatValue]['shipping_vat'] = $subShippingVat[$vatValue];
00328                 }
00329                 else
00330                 {
00331                     $shippingVatList[$vatValue]['shipping_ex_vat'] += $subShippingExVat[$vatValue];
00332                     $shippingVatList[$vatValue]['shipping_inc_vat'] += $subShippingIncVat[$vatValue];
00333                     $shippingVatList[$vatValue]['shipping_vat'] += $subShippingVat[$vatValue];
00334                 }
00335 
00336                 $totalShippingExVat += $subShippingExVat[$vatValue];
00337                 $totalShippingIncVat += $subShippingIncVat[$vatValue];
00338                 $totalShippingVat += $subShippingVat[$vatValue];
00339             }
00340         }
00341         else // made for backwards compability.
00342         {
00343             $vatValue = $shippingInfo['vat_value'];
00344             $shippingCost = $shippingInfo['cost'];
00345             $isVatInc = $shippingInfo['is_vat_inc'];
00346             if ( $isVatInc == 1 )
00347             {
00348                 $divideValue = ( $vatValue / 100 ) + 1;
00349                 $subShippingExVat[$vatValue] = $shippingCost;
00350                 $subShippingIncVat[$vatValue] = ( $shippingCost / $divideValue );
00351                 $subShippingVat[$vatValue] = ( $subShippingIncVat[$vatValue] - $subShippingExVat[$vatValue] );
00352             }
00353             else
00354             {
00355                 $multiplier = ( $vatValue / 100 ) + 1;
00356                 $subShippingExVat[$vatValue] = $shippingCost;
00357                 $subShippingIncVat[$vatValue] = ( $shippingCost * $multiplier );
00358                 $subShippingVat[$vatValue] = ( $subShippingIncVat[$vatValue] - $subShippingExVat[$vatValue] );
00359             }
00360 
00361             $shippingVatList[$vatValue]['shipping_ex_vat'] = $subShippingExVat[$vatValue];
00362             $shippingVatList[$vatValue]['shipping_inc_vat'] = $subShippingIncVat[$vatValue];
00363             $shippingVatList[$vatValue]['shipping_vat'] = $subShippingVat[$vatValue];
00364 
00365             $totalShippingExVat = $subShippingExVat[$vatValue];
00366             $totalShippingIncVat = $subShippingIncVat[$vatValue];
00367             $totalShippingVat = $subShippingVat[$vatValue];
00368         }
00369         $returnArray = array( 'vat_shipping_list_ex_vat' => $subShippingExVat,
00370                               'vat_shipping_list_inc_vat' => $subShippingIncVat,
00371                               'vat_shipping_list_vat' => $subShippingVat,
00372                               'shipping_vat_list' => $shippingVatList,
00373                               'total_shipping_ex_vat' => $totalShippingExVat,
00374                               'total_shipping_inc_vat' => $totalShippingIncVat,
00375                               'total_shipping_vat' => $totalShippingVat );
00376         return $returnArray;
00377     }
00378 
00379 
00380     /*!
00381      Update shipping price with calculated information based on original values.
00382      All values are changed or added directly in the array $basketInfo
00383      \public
00384      \static
00385 
00386      Example on a calculated $basketInfo variable:
00387      \code
00388      array( 'price_info' => array( 0 => array( 'price_ex_vat' => 231,
00389                                                'price_inc_vat' => 231,
00390                                                'price_vat' => 0,
00391                                                'total_price_ex_vat' => 231,
00392                                                'total_price_inc_vat' => 231,
00393                                                'total_price_vat' => 0 ),
00394                                    12 => array( 'total_price_ex_vat' => 50.25,
00395                                                 'total_price_inc_vat' => 56.28,
00396                                                 'total_price_vat' => 6.03 ),
00397                                    25 => array( 'total_price_ex_vat' => 80.6,
00398                                                 'total_price_inc_vat' => 100.75,
00399                                                 'total_price_vat' => 20.15 ) ),
00400             'total_price_info' => array( 'price_ex_vat' => 231,
00401                                          'price_inc_vat' => 231,
00402                                          'price_vat' => 0,
00403                                          'total_price_ex_vat' => 361.85,
00404                                          'total_price_inc_vat' => 388.03,
00405                                          'total_price_vat' => 26.18 ),
00406             'additional_info' => array( 'shipping_items' => array( 12 => array( 'total_price_ex_vat' => 50.25,
00407                                                                                 'total_price_inc_vat' => 56.28,
00408                                                                                 'total_price_vat' => 6.03 ),
00409                                                                    25 => array( 'total_price_ex_vat' => 80.6,
00410                                                                                 'total_price_inc_vat' => 100.75,
00411                                                                                 'total_price_vat' => 20.15 ) ),
00412                                         'shipping_total' => array( 'total_price_ex_vat' => 130.85,
00413                                                                    'total_price_inc_vat' => 157.03,
00414                                                                    'total_price_vat' => 26.18 ) ) );
00415      \endcode
00416     */
00417     static function updatePriceInfo( $productCollectionID, &$basketInfo )
00418     {
00419         $returnValue = false;
00420         if ( is_object( $handler = eZShippingManager::loadBasketInfoHandler() ) )
00421         {
00422             $returnValue = $handler->updatePriceInfo( $productCollectionID, $basketInfo );
00423         }
00424         return $returnValue;
00425     }
00426 }
00427 ?>