En el modelo tax/Sales_Total_Quote_Tax
, hay un método _deltaRound()
que redondea un precio. Agrega un pequeño delta, para detener el comportamiento no determinista al redondear 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;
}
Pero almacena un delta. Si no puede encontrar ese delta almacenado, lo inventa. ¿Por qué? Por lo que puedo decir, esto conduce a resultados diferentes con operaciones idénticas.
Digamos que tenemos un $price
3.595 y no tenemos un caché $delta
. A medida que avanzamos por el método, obtendremos $ delta = 0.000001. Entonces obtenemos $price
= 3.595001, que se redondea a 3.60, por lo que tenemos un nuevo $delta
de -0.004999. Y devolvemos 3.60.
Excepto que ahora tenemos un delta, así que hagámoslo de nuevo, con $price
= 3.595. $price
= 3.595 - 0.004999 = 3.590001
Que si redondeamos, obtenemos 3.59. Diferentes respuestas
Me parece que cualquier algoritmo de redondeo utilizado debería al menos dar la misma respuesta cada vez que se ejecuta con los mismos argumentos, pero no esta vez.
Respuestas:
Tengo Magento 1.8 en mi servidor y he comprobado el
_deltaRound()
método. Se ve así ahora.Como puede ver, si
_roundingDeltas()
no está configurado, tomazero
como valor predeterminado. Es solo por darte cuenta. El equipo de Magento puede escuchar tu duda. Resolvieron tu problema en silencio. :)EDITAR
Analicemos el uso de esta función aplicándola en un ejemplo en tiempo real. Supongamos que tengo un producto en el carrito que está sujeto a impuestos. La cantidad que voy a comprar será, 5. Después de aplicar el impuesto, el producto tiene un precio de $ 10.5356. Entonces esta es mi situación
Así que ahora calculemos el precio real que se producirá en esta situación. Será
Ahora supongamos que magento no usa el
_deltaRound()
método. Simplemente redondea el precio del producto hasta dos decimales y luego calcula el precio total. En este caso, el precio del producto se redondeará10.54
y, por lo tanto, el precio total seríaAhora supongamos que magento está utilizando el
_deltaRound()
método y esta función realmente redondea el precio del producto a dos decimales. Junto con eso, mantendrá un valor delta, que de hecho es la diferencia entre el precio real y el precio redondeado, que se utilizará para calcular el precio redondeado más adelante. aquíEso significa que el
_deltaRound()
método realmente hace que el redondeo de los precios impositivos sea más preciso al precio impositivo real. Como indicó, este método devuelve valores redondos diferentes que dependen del valor delta. Este valor delta hace que el redondeo de impuestos sea más preciso.De acuerdo con esto, podemos concluir que, a medida que aumenta la cantidad, si no adoptamos este método, producirá una gran diferencia entre el valor redondeado y el valor real. Pero si usamos este método, nuestro valor redondeado se acercará lo más posible al valor real.
Magento por defecto redondea a dos decimales. Este es el método responsable del redondeo de dos decimales.
Si lo establecemos en 4 o algo así, podemos aumentar aún más la precisión del redondeo.
Nota: Esta es mi apertura y resumen. Puede o no puede ser cierto. Sin embargo, me parece preciso y lógico.
Gracias.
fuente
roundPrice
_deltaRound()
para superar la dificultad en cierta medida. De todos modos está codificado. Definitivamente producirá algunas dificultades en algunos casosInformacion
Precio redondo en Magento basado en la operación de redondeo anterior delta.
A veces, esto puede causar un error debido al error de cálculo delta alto (
$this->_calculator->round($price)
). Por ejemplo, por esta razón, algunos precios pueden variar en el rango de ± 1 centavo .Solución
Para evitar esto, debe mejorar la precisión del cálculo delta.
Cambio
a
Los cambios deben hacerse en ambos archivos:
¡No modifique ni piratee los archivos principales! ¡Haz una reescritura!
La solución se probó en diferentes versiones de Magento 1.9.x, pero tal vez esto funcione en versiones anteriores.
PD
La
roundPrice
función de cambio , como se muestra a continuación, puede resolver el problema del error de redondeo, pero puede causar otros (por ejemplo, algunas plataformas requieren redondear hasta 2 decimales).fuente