В модели tax/Sales_Total_Quote_Tax
есть метод, _deltaRound()
который округляет цену. Добавляет небольшую дельту, чтобы остановить недетерминированное поведение при округлении 0,5.
/**
* Round price based on previous rounding operation delta
*
* @param float $price
* @param string $rate
* @param bool $direction price including or excluding tax
* @param string $type
* @return float
*/
protected function _deltaRound($price, $rate, $direction, $type = 'regular')
{
if ($price) {
$rate = (string)$rate;
$type = $type . $direction;
// initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
$delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0.000001;
$price += $delta;
$this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
$price = $this->_calculator->round($price);
}
return $price;
}
Но это хранит дельту. Если он не может найти такую сохраненную дельту, он составляет ее. Почему? Насколько я могу судить, это приводит к разным результатам с одинаковыми операциями.
Допустим, у нас есть $price
3,595, и у нас нет кэшированного $delta
. По мере прохождения метода мы получим $ delta = 0.000001. Затем мы получаем $price
= 3,595001, что округляет до 3,60, поэтому мы получаем новое значение $delta
-0,004999. И мы возвращаем 3,60.
За исключением того, что теперь у нас есть дельта, так что давайте сделаем это снова, с $price
= 3,595. $price
= 3,595 - 0,004999 = 3,590001
Что если мы округлим, мы получим 3,59. Разные ответы.
Мне кажется, что любой используемый алгоритм округления должен, по крайней мере, давать один и тот же ответ каждый раз, когда он запускается с теми же аргументами, но не в этот раз.
Ответы:
У меня есть Magento 1.8 на моем сервере, и я проверил
_deltaRound()
метод. Теперь это выглядит так.Как видите, если значение
_roundingDeltas()
не установлено, оно принимаетzero
значение по умолчанию. Это просто для того, чтобы заметить тебя. Команда Magento может подслушать ваши сомнения. Они решили твою проблему молча. :)РЕДАКТИРОВАТЬ
Давайте проанализируем использование этой функции, применив ее в качестве примера в реальном времени. Предположим, у меня есть продукт в корзине, который облагается налогом. Количество, которое я собираюсь приобрести, составляет 5. После применения налога цена на продукт составляет 10,5356 долларов США. Так что это моя ситуация
Итак, теперь давайте посчитаем реальную цену, которую собираемся произвести в этой ситуации. Это будет
Теперь давайте предположим, что magento не использует
_deltaRound()
метод. Он просто округляет цену продукта до двух знаков после запятой, а затем вычисляет общую стоимость. В этом случае цена продукта будет округлена до,10.54
и, следовательно, общая цена будетТеперь давайте предположим, что magento использует
_deltaRound()
метод, и эта функция фактически округляет цену продукта до двух десятичных знаков. Наряду с этим он будет сохранять значение дельты, которое фактически является разницей между фактической ценой и округленной ценой, и будет использоваться для расчета округленной цены позже. ВотЭто означает, что
_deltaRound()
метод фактически делает округление налоговой цены более точным к фактической налоговой оценке. Как вы указали, этот метод возвращает различное значение округления, зависящее от значения дельты. Это значение дельты фактически делает округление налогов более точным.Исходя из этого, мы можем сделать вывод, что по мере увеличения количества, если мы не примем этот метод, он приведет к большой разнице между округленным значением и фактическим значением. Но если мы используем этот метод, он сделает наше округленное значение как можно ближе к фактическому значению.
Magento по умолчанию округляет до двух знаков после запятой. Это метод, который отвечает за округление до двух знаков после запятой
Если мы установим его на 4 или что-то еще, мы можем еще больше повысить точность округления.
Примечание: это мое открытие и обзор. Это может или не может быть правдой. Однако это кажется точным и логичным для меня.
Благодарю.
источник
roundPrice
_deltaRound()
чтобы преодолеть трудности в некоторой степени. Любой, как это жестко закодировано. Это определенно вызовет некоторые трудности в некоторых случаяхИнформация
Цена раунда в Magento основана на предыдущей операции округления delta.
Иногда это может вызвать ошибку из-за ошибки вычисления высокой дельты (
$this->_calculator->round($price)
). Например, по этой причине некоторые цены могут варьироваться в диапазоне ± 1 цент .Решение
Чтобы этого избежать, нужно повысить точность расчета дельты.
+ Изменить
в
Изменения необходимо внести в оба файла:
Не изменяйте и не взламывайте основные файлы! Сделай переписать!
Решение было протестировано на разных версиях Magento 1.9.x, но, возможно, это будет работать в более ранних версиях.
PS
roundPrice
Функция изменения , как показано ниже, может решить проблему ошибки округления, но может вызвать другие (например, некоторые платформы требуют округления до 2 десятичных знаков).источник