/** * Test scenario for issue #13712: Multiprice datatype shows wrong price after multiple calls in template * * Test Outline * ------------ * 1. Create a euro currency * 2. Create a VAT type of 10 % * 3. Create a content class with an attribute of the datatype ezmultiprice * 4. Create a content object of this content class and set a custom price ex. VAT with the VAT type of 10% that we created * 5. Subsequently retrieve the attribute 'inc_vat_price_list' * * @result: the returned eZMultiPriceData instances differ on each call, their values are increased each time with VAT * @expected: the returned eZMultiPriceData instances are equal * @link http://issues.ez.no/13712 * @group issue_13712 */ public function testMultipleCallsToCalculatedPrice() { $currencyCode = 'EUR'; // create currency $currencyParams = array('code' => $currencyCode, 'symbol' => false, 'locale' => 'eng-GB', 'custom_rate_value' => 0, 'rate_factor' => 1); $currency = eZCurrencyData::create($currencyCode, '€', 'eng-GB', 0, 0, 1); $currency->store(); $currencyID = $currency->attribute('id'); $this->assertInternalType('integer', $currencyID); // create VAT type $row = array('name' => 'Test', 'percentage' => 10.0); $vatType = new eZVatType($row); $vatType->store(); $vatTypeID = $vatType->attribute('id'); $this->assertInternalType('integer', $vatTypeID); $class = eZContentClass::create(false, array('name' => 'eZMultiPrice::testMultipleCallsToCalculatedPrice', 'identifier' => 'ezmultiprice_test')); $class->store(); $classID = $class->attribute('id'); $this->assertInternalType('integer', $classID); $attributes = $class->fetchAttributes(); // add class attributes $newAttribute = eZContentClassAttribute::create($classID, 'ezmultiprice', array('name' => 'Test', 'identifier' => 'test')); $dataType = $newAttribute->dataType(); $dataType->initializeClassAttribute($newAttribute); $newAttribute->setAttribute(eZMultiPriceType::DEFAULT_CURRENCY_CODE_FIELD, $currencyCode); $newAttribute->setAttribute(eZMultiPriceType::VAT_ID_FIELD, $vatTypeID); $newAttribute->store(); $attributes[] = $newAttribute; $class->storeDefined($attributes); $contentObject = $class->instantiate(); $version = $contentObject->currentVersion(); $dataMap = $version->dataMap(); $multiPrice = $dataMap['test']->content(); $multiPrice->setAttribute('selected_vat_type', $vatTypeID); $multiPrice->setAttribute('is_vat_included', eZMultiPriceType::EXCLUDED_VAT); $multiPrice->setCustomPrice($currencyCode, 100); $multiPrice->updateAutoPriceList(); $dataMap['test']->setContent($multiPrice); $dataMap['test']->setAttribute('data_text', $vatTypeID . ',' . eZMultiPriceType::EXCLUDED_VAT); $dataMap['test']->store(); // test values $firstIncVatPriceList = $multiPrice->attribute('inc_vat_price_list'); $this->assertArrayHasKey('EUR', $firstIncVatPriceList); $firstCallValue = $firstIncVatPriceList['EUR']->attribute('value'); $secondIncVatPriceList = $multiPrice->attribute('inc_vat_price_list'); $this->assertArrayHasKey('EUR', $secondIncVatPriceList); $secondCallValue = $secondIncVatPriceList['EUR']->attribute('value'); $this->assertEquals($firstCallValue, $secondCallValue); $thirdIncVatPriceList = $multiPrice->attribute('inc_vat_price_list'); $this->assertArrayHasKey('EUR', $thirdIncVatPriceList); $thirdCallValue = $thirdIncVatPriceList['EUR']->attribute('value'); $this->assertEquals($firstCallValue, $thirdCallValue); }
function unserializeContentClassAttribute($classAttribute, $attributeNode, $attributeParametersNode) { $vatNode = $attributeParametersNode->getElementsByTagName('vat-included')->item(0); $vatIncluded = strtolower($vatNode->getAttribute('is-set')) == 'true'; if ($vatIncluded) { $vatIncluded = self::INCLUDED_VAT; } else { $vatIncluded = self::EXCLUDED_VAT; } $classAttribute->setAttribute(self::INCLUDE_VAT_FIELD, $vatIncluded); $vatTypeNode = $attributeParametersNode->getElementsByTagName('vat-type')->item(0); $vatName = $vatTypeNode->getAttribute('name'); $vatPercentage = $vatTypeNode->getAttribute('percentage'); $vatID = false; $vatTypes = eZVatType::fetchList(); foreach ($vatTypes as $vatType) { if ($vatType->attribute('name') == $vatName and $vatType->attribute('percentage') == $vatPercentage) { $vatID = $vatType->attribute('id'); break; } } if (!$vatID) { $vatType = eZVatType::create(); $vatType->setAttribute('name', $vatName); $vatType->setAttribute('percentage', $vatPercentage); $vatType->store(); $vatID = $vatType->attribute('id'); } $classAttribute->setAttribute(self::VAT_ID_FIELD, $vatID); $defaultCurrency = $attributeParametersNode->getElementsByTagName('default-currency')->item(0); $currencyCode = $defaultCurrency->getAttribute('code'); $classAttribute->setAttribute(self::DEFAULT_CURRENCY_CODE_FIELD, $currencyCode); }
function unserializeContentClassAttribute($classAttribute, $attributeNode, $attributeParametersNode) { $vatNode = $attributeParametersNode->getElementsByTagName('vat-included')->item(0); $vatIncluded = strtolower($vatNode->getAttribute('is-set')) == 'true'; $classAttribute->setAttribute(eZPriceType::INCLUDE_VAT_FIELD, $vatIncluded); $vatTypeNode = $attributeParametersNode->getElementsByTagName('vat-type')->item(0); $vatName = $vatTypeNode->getAttribute('name'); $vatPercentage = $vatTypeNode->getAttribute('percentage'); $vatID = false; $vatTypes = eZVatType::fetchList(); foreach ($vatTypes as $vatType) { if ($vatType->attribute('name') == $vatName and $vatType->attribute('percentage') == $vatPercentage) { $vatID = $vatType->attribute('id'); break; } } if (!$vatID) { $vatType = eZVatType::create(); $vatType->setAttribute('name', $vatName); $vatType->setAttribute('percentage', $vatPercentage); $vatType->store(); $vatID = $vatType->attribute('id'); } $classAttribute->setAttribute(eZPriceType::VAT_ID_FIELD, $vatID); }
/** * Return VAT type object. */ function vatTypeObject() { return eZVatType::fetch($this->attribute('vat_type')); }
function VATTypeList() { if (!isset($this->VatTypeList)) { $this->VatTypeList = eZVatType::fetchList(); if (!isset($this->VatTypeList)) { $this->VatTypeList = array(); } } return $this->VatTypeList; }
/** * Choose the best matching VAT type for given product category and country. * * We calculate priority for each VAT type and then choose * the VAT type having the highest priority * (or first of those having the highest priority). * * VAT type priority is calculated from county match and category match as following: * * CountryMatch = 0 * CategoryMatch = 1 * * if ( there is exact match on country ) * CountryMatch = 2 * elseif ( there is weak match on country ) * CountryMatch = 1 * * if ( there is exact match on product category ) * CategoryMatch = 2 * elseif ( there is weak match on product category ) * CategoryMatch = 1 * * if ( there is match on both country and category ) * VatTypePriority = CountryMatch * 2 + CategoryMatch - 2 * else * VatTypePriority = 0 * * \private * \static */ function chooseVatType( $productCategory, $country ) { $vatRules = eZVatRule::fetchList(); $catID = $productCategory->attribute( 'id' ); $vatPriorities = array(); foreach ( $vatRules as $rule ) { $ruleCountry = $rule->attribute( 'country_code' ); $ruleCatIDs = $rule->attribute( 'product_categories_ids' ); $ruleVatID = $rule->attribute( 'vat_type' ); $categoryMatch = 0; $countryMatch = 0; if ( $ruleCountry == '*' ) $countryMatch = 1; elseif ( $ruleCountry == $country ) $countryMatch = 2; if ( !$ruleCatIDs ) $categoryMatch = 1; elseif ( in_array( $catID, $ruleCatIDs ) ) $categoryMatch = 2; if ( $countryMatch && $categoryMatch ) $vatPriority = $countryMatch * 2 + $categoryMatch - 2; else $vatPriority = 0; if ( !isset( $vatPriorities[$vatPriority] ) ) $vatPriorities[$vatPriority] = $ruleVatID; } krsort( $vatPriorities, SORT_NUMERIC ); $bestPriority = 0; if ( $vatPriorities ) { $tmpKeys = array_keys( $vatPriorities ); $bestPriority = array_shift( $tmpKeys ); } if ( $bestPriority == 0 ) { eZDebug::writeError( "Cannot find a suitable VAT type " . "for country '" . $country . "'" . " and category '" . $productCategory->attribute( 'name' ). "'." ); return new eZVatType( array( "id" => 0, "name" => ezpI18n::tr( 'kernel/shop', 'None' ), "percentage" => 0.0 ) ); } $bestVatTypeID = array_shift( $vatPriorities ); $bestVatType = eZVatType::fetch( $bestVatTypeID ); eZDebug::writeDebug( sprintf( "Best matching VAT for '%s'/'%s' is '%s' (%d%%)", $country, $productCategory->attribute( 'name' ), $bestVatType->attribute( 'name' ), $bestVatType->attribute( 'percentage' ) ) ); return $bestVatType; }
/** * Determine dependent VAT rules and products for the given VAT types. * * \private */ function findDependencies( $vatTypeIDList, &$deps, &$haveDeps, &$canRemove ) { // Find dependencies (products and/or VAT rules). $deps = array(); $haveDeps = false; $canRemove = true; foreach ( $vatTypeIDList as $vatID ) { $vatType = eZVatType::fetch( $vatID ); $vatName = $vatType->attribute( 'name' ); // Find dependent VAT rules. $nRules = eZVatRule::fetchCountByVatType( $vatID ); // Find dependent products. $nProducts = eZVatType::fetchDependentProductsCount( $vatID ); // Find product classes having this VAT type set as default. $nClasses = eZVatType::fetchDependentClassesCount( $vatID ); if ( $nClasses ) $canRemove = false; $deps[$vatID] = array( 'name' => $vatName, 'affected_rules_count' => $nRules, 'affected_products_count' => $nProducts, 'affected_classes_count' => $nClasses ); if ( !$haveDeps && ( $nRules > 0 || $nProducts > 0 ) ) $haveDeps = true; } }
if (is_numeric($ruleID)) { $tplVatRule = eZVatRule::fetch($ruleID); $tplCountry = $tplVatRule->attribute('country_code'); $tplCategoryIDs = $tplVatRule->attribute('product_categories_ids'); $tplVatTypeID = $tplVatRule->attribute('vat_type'); $pathText = ezpI18n::tr('kernel/shop/editvatrule', 'Edit VAT charging rule'); } else { $tplVatRule = null; $tplCountry = false; $tplVatTypeID = false; $tplCategoryIDs = array(); $pathText = ezpI18n::tr('kernel/shop/editvatrule', 'Create new VAT charging rule'); } if ($errors !== false) { $tplCountry = $chosenCountry; $tplCategoryIDs = $chosenCategories; $tplVatTypeID = $chosenVatType; } $vatTypes = eZVatType::fetchList(true, true); $tpl = eZTemplate::factory(); $tpl->setVariable('error_header', $errorHeader); $tpl->setVariable('errors', $errors); $tpl->setVariable('all_vat_types', $vatTypes); $tpl->setVariable('all_product_categories', $productCategories); $tpl->setVariable('rule', $tplVatRule); $tpl->setVariable('country_code', $tplCountry); $tpl->setVariable('category_ids', $tplCategoryIDs); $tpl->setVariable('vat_type_id', $tplVatTypeID); $Result = array(); $Result['content'] = $tpl->fetch("design:shop/editvatrule.tpl"); $Result['path'] = array(array('text' => $pathText, 'url' => false));