Wer schon einmal einen Magento-Shop betreut hat, der ist mit hoher Wahrscheinlichkeit auf das Rundungsproblem gestoßen, bei dem immer wieder Rundungsdifferenzen von +/- 1 Cent auftreten. Das Problem ist bereits seit langer Zeit bekannt, und wurde vor kurzem laut Hersteller in der neuesten Version 1.8 beseitigt. Wer sich bereits einmal die Fingern bei einem Magento-Update (sogar bei vermeintlichen kleinen Versionssprüngen) verbrannt hat, für den ist ein Update oftmals keine echte Option. Das erhöhte Risiko, dass - mangels Codequalität im Core und insbesondere von diversen Extensions - andere Fehler auftreten und zumindest Teile des Shops nicht mehr richtig funktionieren, schreckt zu sehr ab. Selbst, wenn man ein Update plant, sollte man sich genügend Zeit dafür reservieren. Wenn also eine schnelle Lösung gefunden werden muss, ist ein Update keine Option.

Auf der Suche nach einer Lösung für 1.7

Sucht man in Google nach diesem Problem, erhält man eine Unmenge an verzweifelten Fragen, sowie Problemlösungsvorschläge. Sie alle zielen darauf ab, die Genauigkeit der Rundungen von normalerweise 2 auf 4 Nachkommastellen zu erhöhen. Datenbankseitig sind alle Preis-Spalten ohnehin auf 4 Nachkommastellen vorbereitet. In der Mage_Core_Model_Store Klasse werden die Zahlen aber hardcodiert immer auf 2 Nachkommastellen gerundet. Damit werden aber wieder Probleme mit PayPal-Zahlungen ausgelöst.

Mittlerweile gibt es eine gratis Extension, die sowohl die Rundungsgenauigkeit erhöht, als auch das damit verbundene PayPal-Problem löst. Aber sind damit tatsächlich alle Probleme gelöst? Die Antwort lautet: leider nein!

...Nettosumme immer noch falsch...

Die Extension sorgte bei unserem Kunden tatsächlich für richtige Gesamt- und Steuerbeträge. Allerdings wurde des öfteren die Nettosumme falsch berechnet. Denn sie war in diesen Fällen immer noch um einen Cent zu hoch! Das Problem trat immer dann auf, wenn die dritte Nachkommastelle bei der Steuer "5" betrug. So wurde vom Gesamtbetrag der ungerundete Steuerbetrag abgezogen, sodass die auch eine "5" an dritter Nachkommastelle hatte. Im Warenkorb, Bestellbestätigung und auf der Rechnung werden diese Beträge aber wieder gerundet angezeigt. Beide Beträge wurden somit fälschlicherweise aufgerundet. Gleiches Problem ergab sich auch mit Rabatten.

Bei unserem Kunden trat das Problem relativ häufig auf, da viele Brutto-Preise als auch die Standardversandkosten auf 99 Cent enden, und die Produkte auch dem österreichischen Mehrwertsteuersatz von 20% unterliegen. Beispiel: EUR 9,99 brutto ergibt ungerundet 8,325 + 1.665.

Problemlösung

Rechnerisch richtig wäre, den gerundeten Steuerbetrag von der Gesamtsumme zu subtrahieren. Dann erhält man auch eine gerundete und richtige Nettosumme. In Magento sind dann noch folgende Anpassungen notwendig:

Zuerst sollte man die bereits erwähnte Xonu RoundingErrorFix Extension installieren. Diese Extension muss leicht modifiziert werden, um die Rabatte richtig zu berücksichtigen. Und zwar sollte die Datei app/code/community/Xonu/RoundingErrorFix/Model/Store.php folgendermaßen verändert werden:

Im Konstruktor:


$this->classList[] = get_class(Mage::getSingleton('salesrule/quote_discount'));

Und dann noch in der foundPrice() Funktion die if-Bedingung durch folgende ersetzen:


if(!empty($trace[$depth]['class']) && in_array($trace[$depth]['class'], $this->classList)) {

Das Hauptproblem in Zusammenhang mit der Steuer wird so aber leider nicht behoben. Denn hier muss man quer verstreut durch den Code alle Stellen ausfindig machen, die die Nettosumme als Gesamtbetrag - Steuerbetrag ausrechnet, und zuvor den Steuerbetrag auf 2 Stellen runden. So muss z.B. die Mage_Tax_Block_Sales_Order_Tax Klasse angepasst werden, sodass in der _initGrandTotal() Funktion die $baseGrandtotalExcl und $grandtotalExcl Variablen mit gerundeten Steuerbeträgen errechnet werden:


$grandtotalExcl     = $grandtotal - round($this->_source->getTaxAmount(), 2);
$baseGrandtotalExcl = $baseGrandtotal - round($this->_source->getBaseTaxAmount(), 2)

Weitere Dateien, die berücksichtigt werden müssen:

  • Mage_Tax_Model_Sales_Pdf_Grandtotal
  • Mage_Adminhtml_Block_Sales_Order_Create_Totals_Grandtotal
  • Mage_Tax_Block_Checkout_Grandtotal

Mit diesen Anpassungen sollte das Rundungsproblem (hoffentlich) endgültig Geschichte sein!

Kommentare12

Klartext

  • Keine HTML-Tags erlaubt.
  • Zeilenumbrüche und Absätze werden automatisch erzeugt.
  • Website- und E-Mail-Adressen werden automatisch in Links umgewandelt.
Der Inhalt dieses Feldes wird nicht öffentlich zugänglich angezeigt.

Rony67

vor 10 years 2 months

Anpassungen in den weitern Dateien?

Hallo, welche Anpassungen sind denn in den genannten weiteren Dateien vorzunehmen?

Sorry, das kann ich auswendig nicht sagen, aber...

... es ist nicht schwer herauszufinden - überall, wo die Gesamtsumme dort ausgerechnet wird. Die Zeilen sehen eh sehr ähnlich aus

PSI

vor 9 years 11 months

Berechnung Rabatt und weiter Codeänderungen

Hi, 

Danke für die tolle Beschreibung. Ich habe die Extension in meinem 1.7.0.2 Store installiert und benötige keine Änderungen damit Rabattcodes / PayPal etc funktionieren. Kann das sein?

Freue mich auf eine Antwort.

 

LG
P

Ja, das kann sein

Bei dieser Thematik spielen einige Faktoren mit: zum einen hängt es natürlich von der Shop-Konfiguration ab (Steuerberechnungsmethode, Brutto- oder Nettopreise, etc.), in weiterer Folge auch von den Preisen, Rabatt- und Steuersätzen selbst. Denn auch wenn hier im Shopsystem Programmierfehler vorliegen bzw die Herangehensweise bei der Berechnung nicht richtig und konsistent ist, ist es letztendlich auch ein mathematisches Problem.
 

scasei

vor 9 years 11 months

Erweiterung
als Vorschlag: /** * Round price * * @param mixed $price * @param int|NULL $precision * @return double */ public function roundPrice($price,$precision = NULL) { if (NULL!==$precision) { return round($price, $precision); } $precision_ret = 2; $trace = debug_backtrace(); $depth = 2; // if(in_array($trace[$depth]['class'], $this->classList)) // if(array_key_exists('class', $trace[$depth]) && $trace[$depth]['class'] == $this->classList[0]) if( empty($trace[$depth]['class']) || !in_array($trace[$depth]['class'], $this->classList) ) { $precision_ret = 4; } return round($price, $precision_ret); } Und in Mage_Adminhtml_Block_Sales_Order_Creditmemo_Create_Adjustments::getShippingAmount Zeile ändern: return Mage::app()->getStore()->roundPrice($shipping,2) * 1; Dann haben es die Kunden einfacher.

Henry Meier

vor 9 years 4 months

Bitte näher erläutern! :)
Ist es möglich bitte genau zu beschreiben wo und was in den einzelnen Klassen anzupassen ist? Also in: -Mage_Tax_Model_Sales_Pdf_Grandtotal -Mage_Adminhtml_Block_Sales_Order_Create_Totals_Grandtotal -Mage_Tax_Block_Checkout_Grandtotal Kleiner Fehler: Oben in der Beschreibung fehlt da abschließende Semikolon. (;) - ->getBaseTaxAmount(), 2);

Mirko W

vor 8 years 6 months

Nun dachte ich, ENDLICH eine
Nun dachte ich, ENDLICH eine Lösung für das Problem gefunden zu haben, aber leider doch nicht... Unter Magento 1.9.2.2 kämpfen wir aktuell ganz massiv mit diesem Problem. Die Xonu-Erweiterung bringt einerseits (scheinbar) Abhilfe - zumindest ohne die hier beschriebenen Änderungen. Andererseits stimmen zum Teil die Steuern im Warenkorb nicht mehr. Schlimmer sind allerdings andere zusätzliche Effekte, die wir beobachten. Da in erster Linie an Endkunden verkauft wird, befinden sich die Preise als brutto-Preise im System. Für ein paar Händler werden Rabatte berechnet und die Preise werden in einem anderen Storeview netto angezeigt. Funktioniert soweit auch ganz gut, aber fügt man nun Produkte zum Warenkorb hinzu, ändern sich im Warenkorb die Preise. Die Produkte kosten bspw. 2,20 netto. Das erste Produkt im Warenkorb, passt. Beim zweiten ebenfalls. Beim dritten steht plötzlich im Warenkorb ein Preis von 2,21. Lösche ich jetzt das dritte Produkt aus dem Warenkorb, dann hat plötzlich das zweite Produkt einen Preis von 2,21! Hier scheinen im System an so vielen Stellen immer wieder Rundungs- oder Berechnungsfehler gemacht zu werden, das ist übel. Die hier beschriebene Lösung konnte ich leider nicht vollständig testen, da einerseits sofort nach Änderung der Xonu-Extension wieder gehäuft 10413-Fehler bei PayPal auftraten und andererseits leider unklar bleibt, was im Detail an den Core-Dateien geändert werden sollte...
Es stimmt, dass vereinzelt immer noch Probleme auftreten können

Der Shop, für den wir diese Lösung entwickelt haben, läuft mittlerweile auch auf einer 1.9er, aber das Problem ist dennoch nicht völlig aus der Welt. Auf Produktebene ist uns nichts aufgefallen, allerdings werden hier überall nur Bruttopreise angezeigt.

Wir hatten aber Probleme mit den Gesamtsummen - sodass Sub Total (exkl. MwSt.) und/oder Grand Total um einen Cent nicht gestimmt hatten. Das Problem haben wir aus der Welt geschafft, in dem wir brutal per Observer auf das sales_quote_adress_collect_totals_after Event die Summen selbst korrigiert haben.

Jetzt treten nur noch unter bestimmten Fällen Probleme auf - und zwar wenn Gutscheine mit Fixpreis-Rabatten eingesetzt werden - hier ist nämlich schon der Sub Total inkl. MwSt manchmal falsch, was eigentlich die Ausgangsbasis für unsere Summenkorrektur ist. Außerdem passen die Beträge bei der Erstellung von Gutschriften manchmal nicht - hier müssten wir vermutlich mit einer ähnlichen Korrektur eingreifen

Tom B.

vor 7 years 3 months

"Wir hatten aber Probleme mit
"Wir hatten aber Probleme mit den Gesamtsummen - sodass Sub Total (exkl. MwSt.) und/oder Grand Total um einen Cent nicht gestimmt hatten." - Das Problem habe ich auch. Bin mir aber nicht sicher wie ich das per Observer behebe (sales_quote_adress_collect_totals_after). Wie berechnet ihr das nach? bzw. nach welchem Vorgehen korrigiert ihr das? Ich habe hier in bestimmten Situation weiterhin 1 cent mehr oder weniger als grand_total.
Wenn ich mich richtig erinnere...

Wenn ich mich richtig erinnere, sind wir folgendermaßen vorgegangen:

  • Wir nehmen als Ausgangswert Sub Total inkl MwSt
  • Auf diesen Wert addieren wir Brutto-Versandkosten, falls vorhanden, und ziehen den Rabattbetrag (natürlich brutto) ab.
  • Damit haben wir die eigentlich korrekte Gesamtsumme
  • Weicht der Wert vom gesetzten Grand Total ab, überschreiben wir diesen mit dem korrekten Wert
  • In weiterer Folge ziehen wir von der Gesamtsumme den Steuerbetrag ab und vergleichen erneut
  • Weicht der errechnete Wert von Subtotal exkl MwSt vom gesetzten ab, überschreiben wir auch diesen Wert

Gregor

vor 7 years

Falsche Endsumme
Hallo, ich bin mir gerade nicht sicher ob es mit dem Rundungs Problem zusammen hängt. Aber vielleicht kann mir ja jemand helfen. Solange ich nur Normale Produkte im Warenkorb habe berechnet er alles korrekt aber sobald ich zb. einen Mindermengenzuschlag habe kommt am ende was völlig falsches raus. Hier mal eine Screen damit es einfach ist. Eigentlich müssten es 62,29 € sein sind aber in der total summe 64,69 € das ganze ohne Mindermengenzuschlag stimmt dann wieder. Die MwSt. wird aber richtig berechnet also für 62,29 € https://owncloud.blungogo.de/index.php/s/sHFetOpZVaSdyBX Danke für eure Hilfe :)
Eigenartig

Hallo Gregor,

das ist tatsächlich eine sehr eigenartige Summe. Anhand der Abweichung könnte man jetzt gar keine Position nennen, die evtl doppelt versteuert o.ä. werden würde. Wir haben in Magento noch nie einen Mindermengenzuschlag benötigt. Es würde mich nicht wundern, wenn sich dort ein eigener Bug verstecken würde. Wenn man sich einmal durch die Tiefen der Summen- und Steuerberechnungen von Magento durchgequält hat, wundern einen solche Fehler überhaupt nicht mehr. Da wird überall wild hin- und hergerechnet, nix ist vereinheitlicht. So kommen wir auch bei bestehenden, gut frequentierten Shops auch nach langer Zeit wieder auf neue Probleme, wie z.B. Steuerberechnung bei der Gutschrifterstellung (im Zusammenhang mit Versandkosten). -> da hilft leider nur eines: debuggen, debuggen, debuggen - und nicht verzweifeln dabei ;) :)