W modelu tax/Sales_Total_Quote_Tax
istnieje metoda _deltaRound()
zaokrąglająca cenę. Dodaje małą deltę, aby zatrzymać niedeterministyczne zachowanie podczas zaokrąglania 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;
}
Ale przechowuje deltę. Jeśli nie może znaleźć takiej przechowywanej delty, tworzy ją. Dlaczego? O ile mogę powiedzieć, prowadzi to do różnych wyników przy identycznych operacjach.
Powiedzmy, że mamy $price
3.595 i nie mamy pamięci podręcznej $delta
. Gdy przejdziemy przez tę metodę, otrzymamy deltę = 0,000001. Otrzymujemy wtedy $price
= 3.595001, co zaokrągla do 3,60, więc mamy nową wartość $delta
-0.004999. I zwracamy 3,60.
Z wyjątkiem tego, że mamy deltę, więc zróbmy to jeszcze raz, z $price
= 3.595. $price
= 3,595 - 0,004999 = 3,590001
Co jeśli zaokrąglimy, otrzymamy 3,59. Różne odpowiedzi.
Wydaje mi się, że każdy zastosowany algorytm zaokrąglania powinien przynajmniej dać tę samą odpowiedź za każdym razem, gdy jest uruchamiany z tymi samymi argumentami, ale nie tym razem.
Odpowiedzi:
Mam Magento 1.8 na moim serwerze i sprawdziłem
_deltaRound()
metodę. Teraz tak to wygląda.Jak widać, jeśli
_roundingDeltas()
nie jest ustawiony, przyjmujezero
jako wartość domyślną. To tylko dla ciebie. Zespół Magento może podsłuchać twoje wątpliwości. Po cichu rozwiązali twój problem. :)EDYTOWAĆ
Przeanalizujmy wykorzystanie tej funkcji przez zastosowanie jej w przykładzie w czasie rzeczywistym. Załóżmy, że mam produkt w koszyku, który podlega opodatkowaniu. Ilość, którą zamierzam kupić, to 5. Po nałożeniu podatku cena prdouct wynosi 10,5356 USD. Więc to moja sytuacja
A zatem obliczmy teraz rzeczywistą cenę, która przyniesie w tej sytuacji. To będzie
Załóżmy teraz, że magento nie używa
_deltaRound()
metody. Po prostu zaokrągla cenę produktu do dwóch miejsc po przecinku, a następnie oblicza cenę całkowitą. W takim przypadku cena produktu zostanie zaokrąglona,10.54
a zatem będzie to cena całkowitaZałóżmy teraz, że magento używa
_deltaRound()
metody i ta funkcja faktycznie zaokrągla cenę produktu do dwóch miejsc po przecinku. Oprócz tego zachowa wartość delta, która w rzeczywistości jest różnicą między ceną rzeczywistą a ceną zaokrągloną, zostanie wykorzystana do późniejszego obliczenia ceny zaokrąglonej. TutajOznacza to, że
_deltaRound()
metoda faktycznie dokładniej zaokrągla cenę podatkową do rzeczywistej ceny podatkowej. Jak powiedziałeś, ta metoda zwraca inną wartość zaokrąglenia zależy od wartości delta. Ta wartość delta faktycznie dokładniej zaokrągla podatki.Zgodnie z tym możemy stwierdzić, że wraz ze wzrostem ilości, jeśli nie zastosujemy tej metody, spowoduje to dużą różnicę między wartością zaokrągloną a wartością rzeczywistą. Ale jeśli użyjemy tej metody, spowoduje to, że nasza zaokrąglona wartość będzie możliwie najbliższa rzeczywistej wartości.
Magento domyślnie zaokrągla do dwóch miejsc po przecinku. Jest to metoda odpowiedzialna za zaokrąglanie dwóch miejsc po przecinku
Jeśli ustawimy wartość 4 lub coś, możemy dodatkowo zwiększyć dokładność zaokrąglania.
Uwaga: To jest moje otwarcie i przegląd. To może być prawda lub nie. Jednak wydaje mi się to trafne i logiczne.
Dzięki.
źródło
roundPrice
_deltaRound()
do pewnego stopnia pokonania trudności. Jakikolwiek jest na stałe zakodowany. W niektórych przypadkach z pewnością spowoduje pewne trudnościInformacje
Cena zaokrąglania w Magento na podstawie poprzedniej operacji zaokrąglania delty.
Czasami może to powodować błąd z powodu błędu obliczania dużej delty (
$this->_calculator->round($price)
). Na przykład z tego powodu niektóre ceny mogą się różnić w przedziale ± 1 cent .Rozwiązanie
Aby tego uniknąć, musisz poprawić dokładność obliczania delty.
Zmiana
do
Zmiany należy wprowadzić w obu plikach:
Nie modyfikuj ani nie rąbaj podstawowych plików! Przeredaguj!
Rozwiązanie przetestowano na różnych wersjach Magento 1.9.x, ale być może zadziała to we wcześniejszych wersjach.
PS
roundPrice
Funkcja zmiany , jak pokazano poniżej, może rozwiązać problem błędu zaokrąglania, ale może powodować inne (na przykład niektóre platformy wymagają zaokrąglania w górę do 2 miejsc po przecinku).źródło