Berechnung mit Nettopreisen

Hallo,

einer unserer Kunden betreibt einen Onlineshop (Oxid CE 4.4), der auf B2B ausgerichtet ist. Somit wurde im Backend eingestellt, dass die Preise in Netto angegeben werden und im Frontend wurde die Templates angepasst, so dass sie die Nettopreise ausgeben. Soweit, so gut.

Nun ist uns allerdings aufgefallen, dass der Shop beim Zusammenrechnen der Preise (z.B. im Warenkorb) fehler macht und grade bei vielen kleinen Artikeln eine Differenz von einigen Cent auftritt.
Scheinbar rechnet Oxid hier mit den Bruttowerten und wandelt dann erst bei der Ausgabe wieder in Netto zurück. Dadurch treten scheinbar Rundungsfehler auf.

Kann man dieses Verhalten standardmäßig ändern?
Zur Not: An welcher Stelle müsste ich Schrauben?

Hallo,

das Thema ist bekannt aber nicht trivial. Die oxarticle Objekte triggern jeweils ein Preisobjekt. Vielelicht findest Du dort einen Ansatz…

Gruß

Genau vor diesem Problem stehe ich auch grad.

Seit letzten Donnerstag sind wir mit dem Oxid-Shop CE 4.6.4 online und haben tags darauf versucht in unserem Warenwirtschaftssystem (Microsoft NAV09) die von Oxid erzeugten Bestellungen zu berechnen. Chancenlos.

Einstellung: Shop ist vollkommen auf Netto-Preise gestellt.
Soweit wird das bislang nachvollziehen können, passiert bei der Berechnung folgendes:
Der Einzel-Nettowert wird auf Einzel-Brutto gerechnet und anschließend auf 2 Nachkommastellen gerundet. Mit diesem gerundeten Bruttowert rechnet der Shop dann weiter.
Das Ganze zieht sich auch durch die Fracht- und Nebenkosten.

Leider macht das unser Warenwirtschaftssystem (und auch alle anderen die wir kennen) genau anders. Gerechnet wird stets mit den Nettowerten und erst am Schluss wird aus der Nettosumme die MwSt. berechnet.

Gelöst haben wir das aktuell nur bedingt:
Wir haben (war in einem Forumspost) die /core/ oxutils.php
In der Zeile 431: return round($sVal + $dprez * ( $sVal >= 0 ? 1 : -1 ), $iCurPrecision);
Geändert auf: return round($sVal + $dprez, 6);

Wir haben übers Wochenende 10 Shop-Bestellungen erhalten und können jetzt wenigsten in der Brutto-Summe gleichlautend buchen. Einziger Nachteil – Paypal-eFire (neueste Version 2.0.2) geht nicht mehr und bricht mit folgendem Fehler ab: Fehlermeldung von PayPal: The totals of the cart item amounts do not match order amounts.

Das passiert aber nicht immer, - warum kann ich aktuell noch nicht sagen. Ich weiss nicht wie das geprüft wird.

Besten Gruss

Mal ein kleines Update, für die, die es interessiert.

Soweit ich das beurteilen kann, rechnet OXID sehr wohl richtig - das Problem ist die Genauigkeit, da OXID an Stellen rundet, an denen ein nettowert-basierendes Warenwirtschaftssystem nicht eingereifen würde / nicht müsste.

Unsere Warenwirtschaftssystem (Microsoft NAV09) rechnet stets mit 5 Dezimalen und das muss man im Shop dementsprechend abbilden. Kann man auch!

Zur Veranschaulichung, habe ich die EURO-Ausgabe mal auf 5-Stellen gedreht.
Im ADMIN, die Währung auf “EUR@ 1.00@ ,@ .@ €@ [B]5[/B]” stellen und schon wird das deutlich. Natürlich ist das jetzt nur für die Ausgabe.

Für eine Ausgabe von 2 Dezimalen, bei 5-stelliger Genauigkeit muss man halt in die oxultil.php manuell eingereifen. Siehe Post davor.

Anbei mal ein Bild für den direkten Vergleich:

Ich denke, es wird jetzt schnell deutlich, warum ich immer den einen Cent gesucht habe.

Einziger Wermutstropfen - der Knackpunkt ist und bleibt das eFire-Paypal-Portlet - Version 2.0.2 - genauer Gesagt der Haken für “Warenkorb in PayPal anzeigen”.

Ist dieser deaktivert, läuft alles wunderbar durch. Das PP-Portlet bezieht sich auf die im Shop eingestellte Genauigkeit.
Sobald der Haken jedoch aktiviert wird, kommt es zur Fehlermeldung: “Fehlermeldung von PayPal: The totals of the cart item amounts do not match order amounts.”

Aktuelle Lösung für mein hier dargestelltes Problem:

  1. oxutils.php - line 431 auf: return round($sVal + $dprez, 5);
  2. PP-Portlet: Haken für “Warenkorb in PayPal anzeigen” deaktiveren.

Beste Grüße
BK

Hallo BK,

versuch mal folgendes (ungetestet):

neues Modul pricemodule.php:

class priceModule extends priceModule_parent
{
    protected function _recalculate()
    {
        if ( $this->_blNetPriceMode ) {
            $this->_dBrutto = self::netto2Brutto($this->_dNetto, $this->_dVat);
            //$this->_dBrutto = oxUtils::getInstance()->fRound($this->_dBrutto);
        } else {
            //$this->_dBrutto = oxUtils::getInstance()->fRound($this->_dBrutto);
            $this->_dNetto  = self::brutto2Netto($this->_dBrutto, $this->_dVat);
        }
    }
}

oxprice => pricemodule

Hierdurch würde man sich das zuviele Runden der Beträge sparen, meiner Meinung nach eh nicht benötigt, da im Frontend bei Ausgabe des Preises nochmals gerundet wird. Siehe Funktionen getBruttoPrice/getNettoPrice.

Viele Grüße
Benny

Hallo BK,

kannst Du bitte nochmal den Screenshot mit dem Berechnungsbeispiel einstellen? Irgendwie ist das nach Deinem Edit weg :frowning:

Gruß

Hallo an alle erst einmal,

wir hatten nun Zeit uns noch einmal ausgiebig mit der Thematik zu beschäftigen.

Der erste Ansatz war die setPrice Methode in der oxBasketItem Klasse (line 332) anzupassen:

00332     public function setPrice( $oPrice )
00333     {
00334         $this->_oPrice = oxNew( 'oxprice' );
00335         [B]$this->_oPrice->setBruttoPriceMode();[/B]
00336         $this->_oPrice->setVat( $oPrice->getVAT() );
00337         $this->_oPrice->addPrice( $oPrice );
00338         $this->_oPrice->multiply( $this->getAmount() );
00339 
00340         $this->_oUnitPrice = oxNew( 'oxprice' );
00341         [B]$this->_oUnitPrice->setBruttoPriceMode();[/B]
00342         $this->_oUnitPrice->setVat( $oPrice->getVAT() );
00343         $this->_oUnitPrice->addPrice( $oPrice );
00344 
00345         $this->_setDeprecatedValues();
00346     }

Hier wird, völlig egal ob netto Preise im Backend verwendet werden, das $_blNetPriceMode Flag in einem oxPrice Objekt auf “false” gesetzt und anschließend berechnen alle folgenden Methoden als ob es sich um einen Brutto Wert handelt.

Nach auskommentieren/ändern dieser Zeile gabs es zumindest keine Rundungsfehler bei der Berechnung einzelner Shopitems mehr. Bei der Berechnung des kompletten Warenkorbs traten immernoch welche auf.
Das liegt wohl einfach daran, dass das besagte Forcen des setBruttoPriceMode bei allen möglichen Methoden zur Berechnung von Posten (Versandkosten, Rabatte, Gutscheine, etc.) angwendet wird.

Ich vermute mal, dass sich die Entwickler dabei etwas gedacht haben, aber ich kann bisher noch nicht nachvollziehen was.
Wenn jemand weiß, warum das so umgesetzt wurde und warum das vielleicht auch so bleiben sollte um bspw. Komplikationen zu vermeiden, dann wäre das super, wenn er hier Bescheid geben würde.

Als Lösung hierzu kann ich jedenfalls bisher folgendes vorschlagen:
(So haben wir es umgesetzt)

In der Klasse oxPrice alle Bedingung, die $_blPriceMode abfragen, ändern

if ($this->_blNetPriceMode)

ändern zu

if ($this->getConfig()->getConfigParam('blEnterNetPrice'))

So wird das blPriceMode Flag des Objekts ignoriert, stattdessen wird immer die Einstellung aus dem Backend verwendet und zwar überall wo ein Price Objekt zum Einsatz kommt.

Alternativ könnte man auch alle “setBruttoPriceMode()” Aufrufe in den anderen Klassen (oxBasket, oxBasketItem) auskommentieren oder druch “setNettoPriceMode()” ersetzten um sicherzugehen, dass auch in jedem Fall in Netto gearbeitet wird.
Hier sind wir uns allerdings nicht sicher, ob oxBasket und oxBasketItem die eizigen betroffenen Klassen sind.

Hallo zusammen,

wie sich mittlerweile gezeigt hat, ist es mit dem deaktivieren des PP-Portlet: Haken für “Warenkorb in PayPal anzeigen” nicht getan. Es wird zwar besser (seltener), dass der Fehler: “The totals of the cart item amounts do not match order amounts.” auftritt, aber er kommt.

Im Debug-Log des PP-Portlets sieht man, dass dort ein Warenkorbbetrag-Prüfwert ermittelt wird, der, auf Grund der geänderten Genauigkeit, nicht mehr übereinstimmt.

Aktuell muss man sich wohl schlicht entscheiden, ob man einen zur Weiterverarbeitung in einer WaWi funktionierenden Warenkorb-Betrag erhält, oder die Zahlung via Paypal prozesssicher abläuft.

PS: Eine Anfrage, ob es eine Möglichkeit für das Portelt gibt braucht Ihr (als Freeuser) gar nicht erst versuchen. Da kommt zwei Wochen lang keine Antwort und als dann eine kam, steht klar drin, dass ein Freeuser keinen Support erhält. Versteh ich natürlich auch, aber ein gekryptetes Portlet kann man halt selbst schlecht anpassen. Blöde Situation.

Überleg grad ernsthaft, ob ich nicht selbst was eigenes zum Thema Paypal einbaue…

Beste Grüße BK

Hallo,

es gibt ein freies PayPal-Modul. Steht auch auf GitHub.

Gruß Joscha

…und hier ist der Hauptthread

http://forum.oxid-esales.com/showthread.php?t=16200

Danke übrigens für deine Ausführungen zum Thema Netto-Preisberechnung.

[QUOTE=jkrug;103223]…und hier ist der Hauptthread

http://forum.oxid-esales.com/showthread.php?t=16200

Danke übrigens für deine Ausführungen zum Thema Netto-Preisberechnung.[/QUOTE]

Kein Problem.
Wir arbeiten ja auch damit und sind schließlich daran interessiert, dass das System sich weiterentwickelt. :slight_smile:

In der Zeile 431: return round($sVal + $dprez * ( $sVal >= 0 ? 1 : -1 ), $iCurPrecision);
Geändert auf: return round($sVal + $dprez, 6);

Ich habe das auch so geändert. Damit habe ich zwar noch “Rundungsprobleme” für die Bruttokunden im Warenkorb, aber OK. Das könnte man den Kunden wohl noch erklären, wenn dann zumindest die Rechnung aus der WaWi mit der Bestell-E-Mail übereinstimmt.

Aber leider passt es dennoch nicht ganz…

Beispiel Brutto-Kunde:
Summe Artikel (netto): 152,46 €
zzgl. MwSt. 19% Betrag: 28,97 €
Summe Artikel (brutto): 181,43 €
Versandkosten : 3,99 €
Gesamtsumme: 185,41 €

  1. Passt das nicht:181,43 + 3,99 = 185,42 €
  2. Ich schätze hier rechnet OXID in netto: (152,46 + 3,35) * 1,19 = 185,41 €. Das ist mir auch lieber, weil die WaWi auch so rechnet und es somit zu keiner Abweichung kommt. Aber die vorhergehende Ausgabe passt nicht, es wäre besser, wenn diese so wäre:
    Summe Artikel (netto): 152,46 €
    Versandkosten (netto) : 3,35 €
    zzgl. MwSt. 19% Betrag: 29,60 €
    Gesamtsumme: 185,41 €

Beispiel Netto-Kunde:
Summe Artikel (netto): 152,46 €
zzgl. MwSt. 19% Betrag: 28,97 €
Summe Artikel (brutto): 181,43 €
Versandkosten : 3,99 €
Gesamtsumme: 185,42 €

  1. Passt in der Ausgabe:181,43 + 3,99 = 185,42 €
  2. Aber die WaWi rechnet wie oben beschrieben erst die Nettobeträge zusammen und addiert dann die MwSt und kommt somit auf 185,41 €.

Gibt es einen Ansatz für um das Problem zu lösen oder umgehen?

[QUOTE=ixtensa;102438]
Nach auskommentieren/ändern dieser Zeile gabs es zumindest keine Rundungsfehler bei der Berechnung einzelner Shopitems mehr.
[/QUOTE]

Einfach auch in oxpricelist ein

    function setBruttoPriceMode(){
        $this->setNettoPriceMode();
    }

schreiben? Das macht mir einen guten Eindruck (bin am gleichen Problem dran)

Grüße, Matthias

Auch an die gleichen problem.
Momentan liegt mein berechnungsfehler im warenkorb.

zB. Netto price in basket

460,85

Called in module

    public function getFUnitPriceNetto() 
    {
        return oxLang::getInstance()->formatCurrency( $this->getUnitPrice()->getNettoPrice() );
    }  

Then the problem, total für 10 stück wird ausgegeben als 4.608,49 €
Called so

public function getFTotalPriceNetto()
    {
        return oxLang::getInstance()->formatCurrency( $this->getPrice()->getNettoPrice() );
    }

Hab vesrshiedenes von diesem thread ausprobiert, ohne erfolg.
Jemand ein vorschlag ?

PS Ein frage warum wird mit brutto preise gerechnet überhaupt ?

Zu mindenstens weiss ich was das problem ist, weiss ich nur nicht wie ich es löse.

Im admin, preis ist 3525.48

  • es gibt ein universal 5% auf alle preise.

So das ergibt ein preis von
3349.21

Aber wenn mann 100 stück im warenkorb liegt, ergibt sich ein endpreis von 334.920,60
Das kommt weil
3525.48 - 5% ist wirklich 3349,206
Und es scheint Oxid rechnet damit, und nicht mir dem vorher gerundeten preis.
Kann jemand hilfen wo ich suchen soll, das zu andern.

weiter forschen ergibt sich das problem mit wie die discounts gerechnet wird.

In oxdiscount, die function applyDiscount muss geandert wirdern von

 $oDiscountPrice->setPrice( $oPrice->getBruttoPrice() / 100 * $this->oxdiscount__oxaddsum->value, $oPrice->getVat()  );

in

$oDiscountPrice->setPrice( $oPrice->getNettoPrice() / 100 * $this->oxdiscount__oxaddsum->value , $oPrice->getVat());

danach hat mann in oxbasket in function _calcItemsPrice

 $oBasketPrice->setBruttoPriceMode();

das auch noch mal, die netto total preis “kaputt” macht.

Höffentlich warst das jetzt :slight_smile:

Weiss jemand warum oxid in brutto überhaupt rechnet ?

  • das kenn ich von kein anderen shop, waren-wirtschaftsystem.

Hallo Community,
was wäre nun der Workaround um diese Rundungsfehler zu beseitigen?
lg
S.K.

[QUOTE=kalina.0404;109975]was wäre nun der Workaround um diese Rundungsfehler zu beseitigen?[/QUOTE]

Meiner Meinung nach ist für eine “richtige” Berechnung im Code schon alles da, nur leider wird im Code oft (fix) setBruttoPriceMode() aufgerufen. Ich habe die Methode einfach mit einem Aufruf von setNettoPriceMode() überschrieben und es war gut. Die Multiplikation mit der Anzahl funktioniert richtig und die Aufsummierung der Posten auch.

Grüße, Matthias

So Leute, ich mal wieder.

Nach update von meiner 4.6.5 Version auf 4.7.3 stehe ich mit dem Thema Rundungsdifferenz wieder am Anfang.

Die Lösung mit Änderung der oxutils.php Zeile 433
orignal auskommentieren: "return round($sVal + $dprez * ( $sVal >= 0 ? 1 : -1 ), $iCurPrecision)"
ersetzt durch: return round($sVal + $dprez, 5);

hat keine Wirkung mehr. Die anderen hier beschriebene Lösungen habe ich auch schon versucht, klappt auch nicht.

Nachdem sich zu diesem Thema hier ja schon einige gemeldet haben, würde mich der aktuelle Lösungsansatz sehr interessieren.

Beste Grüße
BK

Hab nur ich das Problem mit den Rundungsdifferenzen seit 4.7.3, oder war ich nur doof genug up-zu-daten?