Mam kategorię produktów, które (zgodnie z prawem) wymagają zmiany stawki podatkowej, gdy zamawiasz więcej niż określoną ilość. Rozszerzyłem różne modele podatkowe, aby to działało, gdy dodajesz nowy produkt do koszyka, ale mam problemy, gdy użytkownik aktualizuje ilości w koszyku lub dodaje dodatkowe produkty, które przechylają ilości już w koszyku powyżej progu ilość.
Problem 1:
Przede wszystkim nie jestem w 100% świadomy (-ych) wydarzeń. Próbowałem następujących;
checkout_cart_save_after
(w oparciu o to -> https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event )
checkout_cart_update_items_after
(w oparciu o to -> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )
sales_quote_save_before
(w oparciu o to -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )
Problem 2:
Jestem w stanie uzyskać dostęp do artykułów z koszyka, istnieje wiele sposobów, aby to zrobić. Mogę również iterować poszczególne elementy w koszyku, aktualizować właściwości tych przedmiotów, a następnie zapisywać przedmioty (przynajmniej tymczasowo). Jednak nie jestem w stanie zapisać wyceny i przeliczyć podatków w kasie.
Częściowo dlatego, że chociaż mam dostęp do wyceny koszyka, nie jestem pewien, której metody użyć, aby móc do niej napisać.
Co próbowałem:
To, czego próbowałem w zakresie dostępu do zawartości koszyka, zależało od tego, co zaobserwowałem, ale próbowałem wszystkich następujących rzeczy;
1.
$item = $observer->getQuoteItem;
2.
$cart = Mage::getSingleton('checkout/cart');
$cartItems = $cart->getCart()->getItems();
3.
$cart = $observer->getData('cart');
$quote = $cart->getData('quote');
$cartItems = $quote->getAllVisibleItems();
4.
$cartHelper = Mage::helper('checkout/cart');
$cartItems = $cartHelper->getCart()->getItems();
5.
$quote = Mage::getModel('checkout/cart');
$cartItems = $quote->getItems();
Wydaje się, że przynajmniej pozwala mi uzyskać dostęp do wyceny, przejrzeć je i zaktualizować elementy
6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
To pozwala mi aktualizować każdy element cytatu, gdy wykonuję iterację (wydaje mi się, że używam seterów magii, ponieważ nie mogę znaleźć odpowiednich metod). Miałem nadzieję, że będę w stanie zaktualizować identyfikator klasy podatkowej dla wyceny, a następnie ponownie obliczyć podatki. Jeśli użyję następujących (gdzie $ taxClassId różni się od tego, który jest już używany przez każdą pozycję wyceny);
$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;
A następnie zaloguj wyniki;
Mage::log($item->debug(), null,'taxobserver.log', true);
To pokazuje, że rzeczywiście zaktualizowałem ten cytat i zmieniłem identyfikator podatkowy. Jeśli jednak przejdę dalej i spróbuję zapisać zmodyfikowany cytat;
$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();
A następnie ponownie debuguj;
Mage::log($item->debug(), null,'taxobserver.log', true);
Moje zmiany nie zostały zapisane, zmiana pozycji oferty została zresetowana, a sumy koszyka nie są ponownie obliczane. Zaczynam się zastanawiać, czy znalezienie wysokiego budynku do zeskoczenia może być rozwiązaniem tego.
źródło
Odpowiedzi:
Moją sugestią byłoby umieszczenie obserwatora na
sales_quote_collect_totals_before
zdarzeniu, które jest uruchamiane wMage_Sales_Model_Quote::collectTotals
metodzie, zanim rozpocznie się całkowity proces gromadzenia. Następnie z wnętrza tej metody obserwatora, iteruj pozycje wyceny i zmień klasę podatkową na (już załadowany) obiekt produktu, który możesz odzyskać z przedmiotu wyceny.Po ustawieniu informacji o obiekcie produktu, cokolwiek zrobisz, NIE próbuj zapisywać ich w bazie danych. Posiadanie w pamięci klasy podatkowej ustawionej zgodnie z potrzebami dla obiektu produktu będzie wystarczające, aby logika zbierania sum została znaleziona podczas
Mage_Tax_Model_Sales_Total_Quote_Tax
pobierania, na której klasie podatkowej powinien opierać swoje obliczenia. Zapisanie produktu (jak się wydaje, co próbujesz zrobić w powyższym przykładzie kodu) spowoduje poważne problemy z wydajnością, stworzy warunki wyścigu w procesie obliczeń i po prostu nie jest dobrą praktyką.Powodem, dla którego zdarzenia, z którymi próbujesz pracować, nie są możliwe do osiągnięcia tego, co próbujesz osiągnąć, jest to, że wszystkie one powstają po całkowitym obliczeniu, proces ten jest uruchamiany tylko raz przed zapisaniem wyceny.
Warto zwrócić uwagę na proces zbierania sum, że po uruchomieniu, bez wykonywania dodatkowej pracy, nie można wywołać go ponownie, aby ponownie obliczyć na podstawie zmian wprowadzonych do elementów oferty. Zobacz ten fragment, który wziąłem z blogu mojego kolegi, który niedawno zebrał się w procesie zbierania sum:
Jeśli akurat masz ochotę naprawdę zanurzyć się w głębiny tego, jak działa proces zbierania sum, możesz zapoznać się z pierwszą z czterech serii części dotyczących całkowitego zbierania, aby uzyskać bardziej dogłębną lekturę: Odkrywanie kolekcji Magento Podsumowanie: Wprowadzenie
Podsumowując, musisz wychwycić zdarzenie, które jest uruchamiane przed procesem zbierania sum (i przed wywołaniem getAllItems na adresach wyceny), aby zmiany dokonane w elementach były używane przez wszystkich kolekcjonerów. Nie sprawdziłem, czy sugerowane
sales_quote_collect_totals_before
zdarzenie działa przed wywołaniemgetAllItems
adresu podanego w wycenie, ale jestem prawie pewien, że zadziała dla potrzeb. Ale jeśli nie, mam nadzieję, że dostarczyłem wystarczającego kontekstu, abyś zorientował się, które wydarzenie musisz złapać, aby zadziałało.źródło
Jest jeszcze jedno zdarzenie:
sales_quote_item_set_product
w Mage_Sales_Model_Quote_Item :: setProductZa pomocą tego zdarzenia możesz zmodyfikować klasę podatku od produktów. Użyj metody quoteItem getQty, aby znaleźć ilość dodaną do koszyka.
źródło
Może próba zmiany klasy podatkowej może nie być najlepszym podejściem. Dlaczego nie stworzyć podobnego produktu dla produktów korzystających z wyższej klasy podatkowej i ustawić minimalną ilość w koszyku dla tego produktu. Następnie użyć
checkout_cart_update_items_after
do zamiany produktów na podstawie całkowitej ilości w koszyku?To zdecydowanie nie jest „najlepsza praktyka”, ale może pomóc ci myśleć w innym kierunku.
Alternatywnie spróbuj skonfigurować coś w http://www.mageworx.com/multi-fees-magento-extension.html, gdzie dodajesz „opłatę” za dodatkowy podatek. To może być ładniejszy sposób na zrobienie tego, ale nie pojawi się w sumach podatków, a raczej jako dodatkowa linia sumy zamówień.
źródło
Użyj tego
<sales_quote_collect_totals_before>
i w swojej funkcji lubisz
Mam nadzieję, że to zadziała zdecydowanie
źródło