|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZDefaultVATHandler class 00004 // 00005 // Created on: <15-Dec-2005 15:42:29 vs> 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 ezdefaultvathandler.php 00032 */ 00033 00034 /*! 00035 \class eZDefaultVATHandler ezdefaultvathandler.php 00036 \brief Default VAT handler. 00037 00038 Provides basic VAT charging rules. 00039 Resulting VAT percentage may depend on product category 00040 and country the user is from. 00041 */ 00042 00043 class eZDefaultVATHandler 00044 { 00045 /** 00046 * \public 00047 * \static 00048 */ 00049 function getVatPercent( $object, $country ) 00050 { 00051 $productCategory = eZDefaultVATHandler::getProductCategory( $object ); 00052 00053 // If product category is not specified 00054 if ( $productCategory === null ) 00055 { 00056 require_once( 'kernel/classes/ezproductcategory.php' ); 00057 00058 // Default to a fake product category (*) that will produce 00059 // weak match on category for any VAT rule. 00060 $productCategory = new eZProductCategory( array( 'id' => -1, 00061 'name' => '*' ) ); 00062 } 00063 00064 // If country is not specified 00065 if ( !$country ) 00066 { 00067 // Default to a fake country that will produce 00068 // weak match on country for any VAT rule. 00069 $country = '*'; 00070 } 00071 00072 $vatType = eZDefaultVATHandler::chooseVatType( $productCategory, $country ); 00073 00074 return $vatType->attribute( 'percentage' ); 00075 } 00076 00077 /** 00078 * Determine object's product category. 00079 * 00080 * \private 00081 * \static 00082 */ 00083 function getProductCategory( $object ) 00084 { 00085 $ini = eZINI::instance( 'shop.ini' ); 00086 if ( !$ini->hasVariable( 'VATSettings', 'ProductCategoryAttribute' ) ) 00087 { 00088 eZDebug::writeError( "Cannot find product category: please specify its attribute identifier " . 00089 "in the following setting: shop.ini.[VATSettings].ProductCategoryAttribute" ); 00090 return null; 00091 } 00092 00093 $categoryAttributeName = $ini->variable( 'VATSettings', 'ProductCategoryAttribute' ); 00094 00095 if ( !$categoryAttributeName ) 00096 { 00097 eZDebug::writeError( "Cannot find product category: empty attribute name specified " . 00098 "in the following setting: shop.ini.[VATSettings].ProductCategoryAttribute" ); 00099 00100 return null; 00101 } 00102 00103 $productDataMap = $object->attribute( 'data_map' ); 00104 00105 if ( !isset( $productDataMap[$categoryAttributeName] ) ) 00106 { 00107 eZDebug::writeError( "Cannot find product category: there is no attribute '$categoryAttributeName' in object '" . 00108 $object->attribute( 'name' ) . 00109 "' of class '" . 00110 $object->attribute( 'class_name' ) . "'." ); 00111 return null; 00112 } 00113 00114 $categoryAttribute = $productDataMap[$categoryAttributeName]; 00115 $productCategory = $categoryAttribute->attribute( 'content' ); 00116 00117 if ( $productCategory === null ) 00118 { 00119 eZDebug::writeNotice( "Product category is not specified in object '" . 00120 $object->attribute( 'name' ) . 00121 "' of class '" . 00122 $object->attribute( 'class_name' ) . "'." ); 00123 return null; 00124 } 00125 00126 return $productCategory; 00127 } 00128 00129 /** 00130 * Choose the best matching VAT type for given product category and country. 00131 * 00132 * We calculate priority for each VAT type and then choose 00133 * the VAT type having the highest priority 00134 * (or first of those having the highest priority). 00135 * 00136 * VAT type priority is calculated from county match and category match as following: 00137 * 00138 * CountryMatch = 0 00139 * CategoryMatch = 1 00140 * 00141 * if ( <there is exact match on country> ) 00142 * CountryMatch = 2 00143 * elseif ( <there is weak match on country> ) 00144 * CountryMatch = 1 00145 * 00146 * if ( <there is exact match on product category> ) 00147 * CategoryMatch = 2 00148 * elseif ( <there is weak match on product category> ) 00149 * CategoryMatch = 1 00150 * 00151 * if ( <there is match on both country and category ) 00152 * VatTypePriority = CountryMatch * 2 + CategoryMatch - 2 00153 * else 00154 * VatTypePriority = 0 00155 * 00156 * \private 00157 * \static 00158 */ 00159 function chooseVatType( $productCategory, $country ) 00160 { 00161 require_once( 'kernel/classes/ezvatrule.php' ); 00162 00163 $vatRules = eZVatRule::fetchList(); 00164 00165 $catID = $productCategory->attribute( 'id' ); 00166 00167 $vatPriorities = array(); 00168 foreach ( $vatRules as $rule ) 00169 { 00170 $ruleCountry = $rule->attribute( 'country_code' ); 00171 $ruleCatIDs = $rule->attribute( 'product_categories_ids' ); 00172 $ruleVatID = $rule->attribute( 'vat_type' ); 00173 00174 $categoryMatch = 0; 00175 $countryMatch = 0; 00176 00177 if ( $ruleCountry == '*' ) 00178 $countryMatch = 1; 00179 elseif ( $ruleCountry == $country ) 00180 $countryMatch = 2; 00181 00182 if ( !$ruleCatIDs ) 00183 $categoryMatch = 1; 00184 elseif ( in_array( $catID, $ruleCatIDs ) ) 00185 $categoryMatch = 2; 00186 00187 if ( $countryMatch && $categoryMatch ) 00188 $vatPriority = $countryMatch * 2 + $categoryMatch - 2; 00189 else 00190 $vatPriority = 0; 00191 00192 if ( !isset( $vatPriorities[$vatPriority] ) ) 00193 $vatPriorities[$vatPriority] = $ruleVatID; 00194 } 00195 00196 krsort( $vatPriorities, SORT_NUMERIC ); 00197 00198 00199 $bestPriority = 0; 00200 if ( $vatPriorities ) 00201 { 00202 $tmpKeys = array_keys( $vatPriorities ); 00203 $bestPriority = array_shift( $tmpKeys ); 00204 } 00205 00206 if ( $bestPriority == 0 ) 00207 { 00208 eZDebug::writeError( "Cannot find a suitable VAT type " . 00209 "for country '" . $country . "'" . 00210 " and category '" . $productCategory->attribute( 'name' ). "'." ); 00211 00212 return new eZVatType( array( "id" => 0, 00213 "name" => ezi18n( 'kernel/shop', 'None' ), 00214 "percentage" => 0.0 ) ); 00215 } 00216 00217 $bestVatTypeID = array_shift( $vatPriorities ); 00218 $bestVatType = eZVatType::fetch( $bestVatTypeID ); 00219 00220 eZDebug::writeDebug( 00221 sprintf( "Best matching VAT for '%s'/'%s' is '%s' (%d%%)", 00222 $country, 00223 $productCategory->attribute( 'name' ), 00224 $bestVatType->attribute( 'name' ), 00225 $bestVatType->attribute( 'percentage' ) ) ); 00226 00227 return $bestVatType; 00228 } 00229 } 00230 00231 ?>