Im Modell tax/Sales_Total_Quote_Tax
gibt es eine Methode _deltaRound()
, die einen Preis rundet. Es wird ein kleines Delta hinzugefügt, um nichtdeterministisches Verhalten beim Runden von 0,5 zu stoppen.
/**
* 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;
}
Aber es speichert ein Delta. Wenn es ein solches gespeichertes Delta nicht finden kann, bildet es eines. Warum? Soweit ich das beurteilen kann, führt dies bei identischen Operationen zu unterschiedlichen Ergebnissen.
Nehmen wir an, wir haben einen $price
Wert von 3,595 und keinen zwischengespeicherten Wert $delta
. Während wir die Methode durchlaufen, erhalten wir $ delta = 0.000001. Wir bekommen dann $price
= 3.595001, was auf 3.60 rundet, also haben wir einen neuen $delta
von -0.004999. Und wir geben 3,60 zurück.
Außer jetzt haben wir ein Delta, also lass es uns noch einmal machen, mit $price
= 3.595. $price
= 3,595 - 0,004999 = 3,590001
Wenn wir runden, erhalten wir 3,59. Unterschiedliche Antworten.
Es scheint mir, dass jeder verwendete Rundungsalgorithmus jedes Mal, wenn er mit denselben Argumenten ausgeführt wird, mindestens dieselbe Antwort geben sollte, diesmal jedoch nicht.
Antworten:
Ich habe Magento 1.8 auf meinem Server und die
_deltaRound()
Methode überprüft . Es sieht jetzt so aus.Wie Sie sehen, wird der Wert als Standardwert verwendet , wenn der
_roundingDeltas()
nicht festgelegt istzero
. Es ist nur, um dich zu bemerken. Das Magento-Team kann Ihre Zweifel überhören. Sie haben Ihr Problem im Stillen gelöst. :)BEARBEITEN
Analysieren wir die Verwendung dieser Funktion, indem wir sie in einem Echtzeitbeispiel anwenden. Angenommen, ich habe ein steuerpflichtiges Produkt im Warenkorb. Die Menge, die ich kaufen werde, ist 5. Nach dem Anwenden von Steuern hat das Produkt einen Preis von 10.5356 USD. Das ist also meine Situation
Lassen Sie uns nun den tatsächlichen Preis berechnen, der in dieser Situation entstehen wird. Es wird sein
Nehmen wir nun an, dass Magento keine
_deltaRound()
Methode verwendet. Es wird lediglich der Produktpreis auf zwei Dezimalstellen gerundet und anschließend der Gesamtpreis berechnet. In diesem Fall wird der Produktpreis auf gerundet10.54
und somit der GesamtpreisNehmen wir nun an, dass Magento die
_deltaRound()
Methode verwendet und diese Funktion den Produktpreis auf zwei Dezimalstellen rundet. Gleichzeitig wird ein Deltawert beibehalten, der die Differenz zwischen dem tatsächlichen Preis und dem gerundeten Preis darstellt und später zur Berechnung des gerundeten Preises verwendet wird. HierDies bedeutet, dass die
_deltaRound()
Methode die Steuerpreisrundung tatsächlich genauer auf den tatsächlichen Steuerpreis abrundet. Wie Sie angegeben haben, gibt diese Methode unterschiedliche Rundungswerte zurück, die vom Delta-Wert abhängen. Dieser Delta-Wert erhöht die Genauigkeit der Steuerrundung.Demnach können wir schließen, dass sich bei zunehmender Menge, wenn wir diese Methode nicht anwenden, eine große Differenz zwischen gerundetem Wert und tatsächlichem Wert ergibt. Wenn wir diese Methode verwenden, wird unser gerundeter Wert dem tatsächlichen Wert so nahe wie möglich kommen.
Magento rundet standardmäßig auf zwei Dezimalstellen. Dies ist die Methode, die für das Runden mit zwei Dezimalstellen verantwortlich ist
Wenn wir den Wert auf 4 oder so setzen, können wir die Rundungsgenauigkeit weiter erhöhen.
Hinweis: Dies ist meine Meinung und Übersicht. Es kann wahr sein oder nicht. Es erscheint mir jedoch richtig und logisch.
Vielen Dank.
quelle
roundPrice
_deltaRound()
kann man die Schwierigkeit ein Stück weit überwinden. Irgendwie ist es hart codiert. Es wird definitiv einige Schwierigkeiten in einigen Fällen produzierenDie Info
Rundungspreis in Magento basierend auf dem vorherigen Rundungsoperations-Delta.
Manchmal kann dies aufgrund des Fehlers bei der Berechnung des hohen Deltas (
$this->_calculator->round($price)
) zu einem Fehler führen . Beispielsweise können aus diesem Grund einige Preise im Bereich von variieren ± 1 Cent .Lösung
Um dies zu vermeiden, müssen Sie die Genauigkeit der Delta-Berechnung verbessern.
Veränderung
zu
Änderungen müssen in beiden Dateien vorgenommen werden:
Ändern oder hacken Sie keine Core-Dateien! Mach ein Rewrite!
Die Lösung wurde auf verschiedenen Versionen von Magento 1.9.x getestet, aber möglicherweise funktioniert dies in früheren Versionen.
PS
Die Änderungsfunktion
roundPrice
, wie unten gezeigt, kann das Rundungsfehlerproblem lösen, aber andere verursachen (zum Beispiel erfordern einige Plattformen das Runden auf 2 Dezimalstellen).quelle