32 $params = $event->getParameters();
36 $oldBaseRate = (float)$params[
'OLD_BASE_RATE'];
37 if ($oldBaseRate < 1E-4)
39 $currentBaseRate = (float)$params[
'CURRENT_BASE_RATE'];
40 if (abs($currentBaseRate - $oldBaseRate)/$oldBaseRate < 1E-4)
42 $currency = $params[
'CURRENCY'];
44 $conn = Main\Application::getConnection();
45 $helper = $conn->getSqlHelper();
48 ' set '.$helper->quote(
'PRICE_SCALE').
' = '.$helper->quote(
'PRICE').
' * '.$currentBaseRate.
49 ' where '.$helper->quote(
'CURRENCY').
' = \''.$helper->forSql($currency).
'\'';
50 $conn->queryExecute($query);
52 if (defined(
'BX_COMP_MANAGED_CACHE'))
54 $taggedCache = Main\Application::getInstance()->getTaggedCache();
55 $taggedCache->clearByTag(
'currency_id_'.$currency);
65 public static function loadRoundRules(array $priceTypes)
67 if (empty($priceTypes))
69 Main\Type\Collection::normalizeArrayValuesByInt($priceTypes);
70 if (empty($priceTypes))
73 $skipCache = (defined(
'CATALOG_SKIP_CACHE') && CATALOG_SKIP_CACHE);
74 $cacheTime = (int)self::CACHE_TIME;
76 $managedCache = Main\Application::getInstance()->getManagedCache();
79 foreach ($priceTypes as $priceTypeId)
81 if (!isset(self::$roundRules[$priceTypeId]))
84 $cacheId = static::getRulesCacheId($priceTypeId);
91 self::$roundRules[$priceTypeId] = $managedCache->get($cacheId);
94 if ($skipCache || !$rulesFound)
95 $needLoad[] = $priceTypeId;
96 unset($cacheId, $rulesFound);
101 if (!empty($needLoad))
103 foreach ($needLoad as $priceTypeId)
104 self::$roundRules[$priceTypeId] = array();
106 $iterator = Catalog\RoundingTable::getList(array(
107 'select' => array(
'PRICE',
'ROUND_TYPE',
'ROUND_PRECISION',
'CATALOG_GROUP_ID'),
108 'filter' => array(
'@CATALOG_GROUP_ID' => $needLoad),
109 'order' => array(
'CATALOG_GROUP_ID' =>
'ASC',
'PRICE' =>
'DESC')
111 while ($row = $iterator->fetch())
113 $priceTypeId = (int)$row[
'CATALOG_GROUP_ID'];
114 self::$roundRules[$priceTypeId][] = $row;
117 unset($row, $iterator);
121 foreach ($needLoad as $priceTypeId)
122 $managedCache->set(static::getRulesCacheId($priceTypeId), self::$roundRules[$priceTypeId]);
127 unset($managedCache, $cacheTime, $skipCache);
138 $priceType = (int)$priceType;
141 if (!isset(self::$roundRules[$priceType]))
142 static::loadRoundRules(array($priceType));
144 return self::$roundRules[$priceType];
155 $priceType = (int)$priceType;
158 if (isset(self::$roundRules[$priceType]))
159 unset(self::$roundRules[$priceType]);
160 Main\Application::getInstance()->getManagedCache()->clean(
161 static::getRulesCacheId($priceType),
180 $rules = static::getRoundRules($priceType);
183 foreach ($rules as $row)
185 if ($row[
'PRICE'] < $price)
199 public static function roundPrice($priceType, $price, $currency)
201 $price = (float)$price;
204 $priceType = (int)$priceType;
207 $rule = static::searchRoundRule($priceType, $price, $currency);
210 return static::roundValue($price, $rule[
'ROUND_PRECISION'], $rule[
'ROUND_TYPE']);
227 $precision = (float)$precision;
231 $precision = (int)$precision;
233 $value = (float)$value;
234 if (abs($value) <= self::VALUE_EPS)
237 return ($precision < 1
238 ? static::roundFraction($value, $precision, $type)
239 : static::roundWhole($value, $precision, $type)
251 return self::CACHE_ID.$priceType;
262 protected static function roundWhole($value, $precision, $type)
264 $quotient = $value/$precision;
265 $quotientFloor = floor($quotient);
268 case Catalog\RoundingTable::ROUND_UP:
269 if (($quotient - $quotientFloor) > self::VALUE_EPS)
272 case Catalog\RoundingTable::ROUND_DOWN:
273 if ($quotientFloor < floor(($value + self::VALUE_EPS)/$precision))
276 case Catalog\RoundingTable::ROUND_MATH:
278 if (($quotient - $quotientFloor + self::VALUE_EPS) >= .5)
283 return $quotientFloor*$precision;
296 $valueFloor = floor($value);
297 $fraction = $value - $valueFloor;
298 if ($fraction <= self::VALUE_EPS)
301 return $valueFloor + static::roundWhole($fraction, $precision, $type);