Alışveriş sepeti teklif kalemlerinde vergi oranını değiştirin ve yeniden hesaplayın


31

Belirli bir miktardan daha fazla sipariş verirken (yasal olarak) vergi oranlarını değiştirmesi gereken ürünler kategorisine sahibim. Alışveriş sepetine yeni bir ürün eklediğinizde bu çalışmayı sağlamak için çeşitli vergi modellerini genişlettim, ancak kullanıcı alışveriş sepetindeki miktarları güncellediğinde veya alışveriş sepetindeki miktarları eşiğin üzerinde belirten ek ürünler eklediğinde sorun yaşıyorum Miktar.

Sorun 1:

Her şeyden önce, hangi olayları gözlemleyeceğimi% 100 değilim. Aşağıdakileri denedim;

checkout_cart_save_after(buna dayanarak -> https://stackoverflow.com/questions/14362702/magento-programatic-update-cart-via-event )

checkout_cart_update_items_after(buna dayanarak -> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )

sales_quote_save_before(buna dayanarak -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )

Sorun 2:

Fiyat teklifine ürün sepetinden erişebiliyorum, göründüğü gibi yapmanın bir sürü yolu var. Ayrıca alışveriş sepetindeki bireysel öğeleri yineleyebilir, bu öğelerin özelliklerini güncelleyebilir ve sonra öğeleri kaydedebilirim (en azından geçici olarak). Ancak, o zaman teklifi kaydetmek ve kasada vergileri yeniden hesaplamak mümkün değildir.

Sebeplerin bir kısmı, alışveriş sepetinin fiyatına erişebilirken, hangi yöntemi kullanabileceğime emin olamıyorum.

Ne Denedim?

Alışveriş sepetinin içeriğine erişmek konusunda denediklerim, gözlemlediğim olaya bağlı, ancak aşağıdakilerin hepsini denedim;

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(); 

En azından teklife erişmeme, içinden geçmeme ve kalemleri güncellememe izin veren gibi görünüyor.

6.
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();

Bu, yinelendiğimde her bir teklif öğesini güncellememe izin veriyor (karşılık gelen herhangi bir yöntem bulamadığım için sihirli ayarlayıcıları kullandığımı düşünüyorum). Teklif kalemi için Vergi Sınıfı Kimliğini güncelleyebileceğimi ve vergileri yeniden hesaplayabileceğimi umuyordum. Aşağıdakileri kullanırsam (burada $ taxClassId, her bir teklif öğesi tarafından zaten kullanılandan farklı);

$item->setTaxClassId( $taxClassId );
$item->getProduct()->setIsSuperMode(true);
$item->save;

Ve sonra sonuçları günlüğe kaydedin;

Mage::log($item->debug(), null,'taxobserver.log', true);

Bu teklif öğesini gerçekten güncellediğimi ve vergi kimliğimi değiştirdiğimi gösteriyor. Ancak, o zaman izler ve değiştirilmiş teklifi kaydetmeye çalışırsam;

$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();     

Ve sonra tekrar hata ayıklama;

Mage::log($item->debug(), null,'taxobserver.log', true);

Değişikliklerim kaydedilmedi, teklif kalemi değişikliği sıfırlandı ve alışveriş sepeti toplamları yeniden hesaplanmadı. Atlamak için yüksek bir bina bulmak olup olmadığını merak etmeye başlamak bunun için bir çözüm olabilir.


Lütfen kimse bu sorunu çözmek için bana yardım etsin: stackoverflow.com/questions/27978781/… teşekkür ederim.
Satka

Yanıtlar:


35

Benim önerim , toplam tahsilat sürecine başlamadan önce yöntemde sales_quote_collect_totals_beforeateşlenen olaya bir gözlemci koymak olacaktır Mage_Sales_Model_Quote::collectTotals. Ardından, bu gözlemci yönteminin içinden, teklif öğelerini yineleyin ve teklif öğesinden alabileceğiniz (zaten yüklü) ürün nesnesindeki vergi sınıfını değiştirin.

Ürün nesnesindeki bilgileri ayarladıktan sonra, ne yaparsanız yapın, veritabanına kaydetmeye ÇALIŞMAYIN. Vergi sınıfının hafızada ürün nesnesine gerektiği gibi ayarlanması, toplamada Mage_Tax_Model_Sales_Total_Quote_Taxhesaplanan toplam vergi mantığını hesaplamak için hangi vergi sınıfına dayanması gerektiği konusunda yeterli olacaktır. Ürünü kaydetmek (yukarıdaki kod numaranızda yapmaya çalıştığınız gibi) büyük performans sorunlarına neden olacak, hesaplama sürecinde yarış koşulları yaratacaktır ve sadece iyi bir uygulama değildir.

Çalışmaya çalıştığınız olayların, başarmaya çalıştığınız şeyi başarmanıza olanak sağlamamasının nedeni, hepsinin toplam hesaplamanın ardından gelmesidir.

Toplama toplamı işlemine dikkat çekmeye değer, bir kere çalıştırıldığında, fazladan bir iş yapmadan, teklif öğelerinde yaptığınız değişiklikleri temel alarak yeniden hesaplamak için tekrar arayamazsınız. Blog serisinden aldığım ve şu anda bir iş arkadaşımdan topladığım toplam toplama işlemine koyduğum şu bağlantı parçasına bakın:

Toplam toplama işlemi sırasında neler olduğunu anladığınıza göre, doğrudan kendiniz aramak için uygun veya gerekli bulabilirsiniz. CollectTotals'ı kendi amaçlarınız için kullanmaktan çok emin olmaya başlamadan önce, aşağıdaki kuralı göz önünde bulundurun:

CollectTotals çalıştırıldıktan sonra ürünler teklife eklenemez!

. . . alıntı adreslerinin öğe önbellekleri temizlenmezse

Neredeyse her toplam modelin "bir araya getirme" yöntemi, teklif öğelerini adresden almaya ve bunlar arasında dolaşmaya dayanır. GetAllItems, ilk kez bir teklif adresinde çalıştırıldığında, öğe koleksiyonu aslında benzersiz bir anahtarla önbelleğe alınır ve bu, sonraki aramalarda döndürülen önbelleğe alınmış koleksiyondur.

Toplama toplamı işleminin nasıl çalıştığının derinliğine gerçekten dalmak için bir mürekkeplenme yaşarsanız, daha derinlikli bir okuma için dört toplama serisinin ilkini toplam toplama alanında burada görebilirsiniz: Magento'nun toplamını çözmek

Özetlemek için, toplama toplamı işleminden önce (ve getAllItems'in teklif adreslerinde çağrılmasından önce), böylece öğelerde yaptığınız değişikliklerin toplam toplayıcılar tarafından kullanılacağı bir etkinlik yakalamanız gerekir. Önerilen sales_quote_collect_totals_beforeetkinliğin getAllItemsteklif adresine yapılan herhangi bir çağrıdan önce yayınlandığını doğrulamamıştım , ancak ihtiyacınız olan şey için işe yarayacağından neredeyse eminim. Ama değilse, umarım, çalışması için hangi olayı yakalamanız gerektiğini anlamanız için yeterli bağlamı sağladım.


Bu cevap umduğumun ötesinde. Zaman ayırdığınız için teşekkürler. Harika cevap
McNab

Ahh! Bütün gününü bu işe harcadıktan ve işe alamadan sonra II, nihayet modülün başka bir yerinde kötü yazılmış bir modele düştüğünü fark etti. Bu mükemmel çalışıyor ve ondan bir sürü şey öğrendim, tekrar teşekkürler David.
McNab

@ McNab Çalışmasını sağladığına sevindim. Magento'nun ele alması daha karmaşık alanlardan biri. :)
davidalger

Bağlantılı blogda +1. Okuduğum ilk birkaç kez görmezden geldim. Bu büyük bir yardım.
pspahn 08

6

Başka bir olay daha var: sales_quote_item_set_productMage_Sales_Model_Quote_Item :: setProduct içinde

Mage::dispatchEvent('sales_quote_item_set_product', array(
            'product' => $product,
            'quote_item'=>$this
        ));

Bu olayı kullanarak ürün vergisi sınıfını değiştirebilirsiniz. Sepetinize eklenen miktarı bulmak için quoteItem getQty yöntemini kullanın.


Bunun için teşekkürler, bilmek faydalıdır - @ davidalger'in cevabına dayanarak, şu anda ürünün vergi sınıfını değiştirmemem gerektiğini, teklif modelini değiştirmem gerektiğini biliyorum. Yine de bilmek güzel.
McNab

Aslında, teklif kalemi vergi sınıfını değiştirebilir, olaydaki quoteItem nesnesine de erişebilirsiniz.
PandaWebStudio

Ah tamam - yanlış anladım.
Aydınlattığınız

@PandaWebStudio, fiyat teklifi için nasıl özel vergi tutarı belirlenir? işte benim sorum, magento.stackexchange.com/questions/274520/…
jafar pinjar

2

Belki vergi sınıfını değiştirmeye çalışmak en iyi yaklaşım olmayabilir. Neden daha yüksek vergi sınıfını kullanan ve o ürün için sepetinde minimum miktar ayarlayan ürünler için benzer bir ürün yaratmıyorsunuz? Sonra checkout_cart_update_items_aftersepetindeki toplam adete göre ürünleri değiştirmek için kullanın ?

Bu kesinlikle 'en iyi uygulama' değildir, ancak başka bir yönde düşünmenize yardımcı olabilir.

Alternatif olarak , ekstra vergi için bir 'ücret' eklediğiniz http://www.mageworx.com/multi-fees-magento-extension.html ile bir şeyler ayarlamayı deneyin . Bu aslında bunu yapmanın daha iyi bir yolu olabilir, ancak vergi toplamlarında görünmeyecek, daha fazla sipariş toplam satırı olarak görünmeyecektir.


Cevabınız için teşekkürler Sander. Bu iyi bir fikir ve bunu hiç düşünmemiştim. Size neden hoşlanmadığımı söyleyeyim - temel ürünlerin hepsi Unirgy'nin uMarketplace paketi olsa da çalışıyor ve fiyat karşılaştırma sitesi olarak çalıştığı yere getirilmesi bir işin canavarıydı. Bunun büyük bir iş olabileceğini düşünüyorum. Bu fiyat teklifinin güncellenmesini alamazsam, yine de bakmak zorunda kalacağım.
McNab

Kahretsin, bu ödülle ilgili tüm temsilcilerimi harcadığım için cevabınızı bile yükseltemiyorum! +1 :) Biraz daha aldığımda çok fazla oy alacak.
McNab

haha sorun değil, sorunu anlıyorum ve bu durum için iyi bir çözüm olmaz. Muhtemelen multifees ile giderdim, o zaman bu 'temizleyici' bir çözüm
Sander Mangel

FWIW, bu rotayı önermeyeceğim… eğer sadece satış için muhasebe yapmayı ve envanteri potansiyel bir kabus yapsa. OP'nin dediği gibi, en iyi uygulama değil, ekleyeceğim: Çözeceğinden daha fazla sıkıntıya neden olur.
davidalger

0

Bunu kullan <sales_quote_collect_totals_before>

ve işlevinde seversin

 public function quoteCollectTotalsBefore(Varien_Event_Observer $observer)
    $quote = $observer->getQuote();
    foreach ($quote->getAllItems() as $item)
    {
        $product = $item->getProduct();
        $product->setTaxClassId($product_tax_class_id);
    }
 }

Umarım bu kesinlikle işe yarayacak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.