No modelo tax/Sales_Total_Quote_Tax
, existe um método _deltaRound()
que arredonda um preço. Ele adiciona um delta pequeno, para interromper o comportamento não determinístico ao arredondar 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;
}
Mas ele armazena um delta. Se não conseguir encontrar um delta armazenado, cria um. Por quê? Pelo alcatrão que posso dizer, isso leva a resultados diferentes com operações idênticas.
Digamos que temos um $price
de 3.595 e não temos um cache $delta
. À medida que avançamos no método, obteremos $ delta = 0.000001. Em seguida, obtemos $price
= 3.595001, que arredonda para 3,60, portanto, temos um novo $delta
de -0,004999. E retornamos 3,60.
Exceto agora que temos um delta, então vamos fazê-lo novamente, com $price
= 3.595. $price
= 3.595 - 0.004999 = 3.590001
Se arredondarmos, obteremos 3,59. Respostas diferentes.
Parece-me que qualquer algoritmo de arredondamento usado deve pelo menos dar a mesma resposta toda vez que é executado com os mesmos argumentos, mas não desta vez.
Respostas:
Eu tenho o Magento 1.8 no meu servidor e verifiquei o
_deltaRound()
método. Parece assim agora.Como você pode ver, se o
_roundingDeltas()
não estiver definido, ele assumirázero
como valor padrão. É apenas para perceber você. A equipe Magento pode ouvir sua dúvida. Eles resolveram seu problema silenciosamente. :)EDITAR
Vamos analisar o uso dessa função, aplicando-a em um exemplo em tempo real. Suponha que eu tenha um produto no carrinho tributável. A quantidade que comprarei será 5. Após aplicar o imposto, o produto terá um preço de US $ 10,5356. Então esta é a minha situação
Então agora vamos calcular o preço real que vai produzir nessa situação. Será
Agora vamos assumir que o magento não usa o
_deltaRound()
método Ele apenas arredonda o preço do produto até duas casas decimais e depois calcula o preço total. Nesse caso, o preço do produto será arredondado para,10.54
portanto, o preço total seriaAgora, vamos supor que o magento esteja usando o
_deltaRound()
método e essa função realmente arredonda o preço do produto para duas casas decimais. Junto com isso, ele manterá um valor delta, que é de fato a diferença entre o preço real e o preço arredondado, será usado para calcular o preço arredondado posteriormente. AquiIsso significa que o
_deltaRound()
método realmente torna o arredondamento do preço do imposto mais preciso do preço real do imposto. Como você declarou, esse método retorna um valor arredondado diferente, dependendo do valor delta. Esse valor delta realmente torna o arredondamento de impostos mais preciso.De acordo com isso, podemos concluir que, à medida que a quantidade aumenta, se não estivermos adotando esse método, ele produzirá uma grande diferença entre o valor arredondado e o valor real. Mas se usarmos esse método, o valor arredondado será o mais próximo possível do valor real.
Por padrão, o Magento arredonda para duas casas decimais. Este é o método responsável por arredondar duas casas decimais
Se definirmos para 4 ou algo assim, podemos aumentar ainda mais a precisão do arredondamento.
Nota: Esta é a minha abertura e visão geral. Pode ou não ser verdade. No entanto, parece preciso e lógico para mim.
Obrigado.
fonte
roundPrice
_deltaRound()
para superar a dificuldade em certa medida. Qualquer como é codificado. Ele vai certamente prodcuce algumas dificuldades em alguns casosInfo
Preço da rodada no Magento com base no delta anterior da operação de arredondamento.
Às vezes, isso pode causar um erro devido ao erro de cálculo do delta alto (
$this->_calculator->round($price)
). Por exemplo, por esse motivo, alguns preços podem variar na faixa de ± 1 centavo .Solução
Para evitar isso, você precisa melhorar a precisão do cálculo delta.
mudança
para
É necessário fazer alterações nos dois arquivos:
Não modifique ou corte os arquivos principais! Faça uma reescrita!
A solução foi testada em diferentes versões do Magento 1.9.x, mas talvez isso funcione em versões anteriores.
PS
A
roundPrice
função de alteração , como mostrado abaixo, pode resolver o problema do erro de arredondamento, mas pode causar outros (por exemplo, algumas plataformas exigem o arredondamento de até duas casas decimais).fonte