Ubah tarif pajak untuk item-item penawaran troli dan hitung ulang

31

Saya memiliki kategori produk yang (secara hukum) perlu mengubah tarif pajaknya saat Anda memesan lebih dari jumlah tertentu. Saya telah memperluas berbagai model pajak agar ini berfungsi ketika Anda menambahkan produk baru ke troli, tetapi saya mengalami masalah ketika pengguna memperbarui jumlah di troli atau menambahkan produk tambahan yang memberi tip jumlah yang sudah ada di troli melewati ambang jumlah.

Masalah 1:

Pertama-tama, saya tidak 100% acara yang harus diamati. Saya sudah mencoba yang berikut ini;

checkout_cart_save_after(berdasarkan ini -> https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event )

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

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

Masalah 2:

Saya dapat mengakses item kutipan dari troli, ada banyak cara untuk melakukannya. Saya juga dapat melakukan iterasi melalui item individual di troli, memperbarui properti item tersebut dan kemudian menyimpan item (setidaknya untuk sementara). Namun, saya tidak dapat menyimpan kutipan dan menghitung kembali pajak di kasir.

Sebagian alasannya adalah bahwa sementara saya dapat mengakses kutipan keranjang, saya tidak yakin metode mana yang digunakan untuk dapat menulis kepadanya.

Apa yang Sudah Saya Coba:

Apa yang saya coba dalam hal mengakses isi troli tergantung pada peristiwa yang saya amati tetapi saya sudah mencoba semua hal berikut;

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

Salah satu yang tampaknya setidaknya memungkinkan saya untuk mengakses kutipan, menjalankannya dan memperbarui item

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

Ini memungkinkan saya untuk memperbarui setiap item kutipan ketika saya mengulanginya (saya percaya menggunakan setter ajaib karena saya tidak dapat menemukan metode yang sesuai). Saya berharap dapat memperbarui ID Kelas Pajak untuk item penawaran dan kemudian menghitung ulang pajak. Jika saya menggunakan yang berikut (di mana $ taxClassId berbeda dengan yang sudah digunakan oleh setiap item penawaran);

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

Dan kemudian catat hasilnya;

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

Ini menunjukkan bahwa saya memang memperbarui item kutipan ini dan mengubah ID pajak. Namun, jika saya kemudian menindaklanjuti dan mencoba menyimpan kutipan yang dimodifikasi;

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

Dan kemudian debug lagi;

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

Perubahan saya belum disimpan, perubahan item kutipan telah diatur ulang dan total keranjang tidak dihitung ulang. Mulai bertanya-tanya apakah menemukan gedung tinggi untuk melompat mungkin menjadi solusi untuk yang satu ini.

McNab
sumber
tolong ada yang membantu saya untuk menyelesaikan ini: stackoverflow.com/questions/27978781/… terima kasih.
satish

Jawaban:

35

Saran saya adalah menempatkan pengamat pada sales_quote_collect_totals_beforeacara yang dipecat diMage_Sales_Model_Quote::collectTotals metode sebelum memulai proses pengumpulan total. Kemudian dari dalam metode pengamat ini, ulangi item-item kuotasi dan ubah kelas pajak pada objek produk (yang sudah dimuat) yang dapat Anda ambil dari item kuotasi.

Setelah Anda mengatur informasi tentang objek produk, apa pun yang Anda lakukan, JANGAN mencoba dan menyimpannya ke database. Memiliki kelas pajak yang ditetapkan sesuai kebutuhan pada objek produk dalam memori akan cukup baik untuk memiliki logika kumpulkan total yang ditemukan di Mage_Tax_Model_Sales_Total_Quote_Taxkelas pajak mana yang harus dijadikan dasar perhitungannya. Menyimpan produk (seperti yang Anda coba lakukan dalam contoh kode Anda di atas) akan menyebabkan masalah kinerja utama, akan menciptakan kondisi balapan dalam proses perhitungan, dan sama sekali bukan praktik yang baik.

Alasan bahwa peristiwa yang Anda coba kerjakan tidak memungkinkan Anda untuk mencapai apa yang ingin Anda capai adalah karena semuanya datang setelah perhitungan total, suatu proses yang hanya dijalankan sekali sebelum menyimpan kutipan.

Layak menunjukkan tentang proses kumpulkan total adalah bahwa sekali dijalankan, tanpa melakukan pekerjaan tambahan, Anda tidak dapat memanggilnya lagi untuk menghitung ulang berdasarkan perubahan yang Anda buat pada item penawaran. Lihat tie-bit yang saya ambil dari seri blog ini yang baru-baru ini dikumpulkan oleh rekan saya dalam proses kumpulkan total:

Sekarang setelah Anda memahami apa yang terjadi selama proses pengumpulan total, Anda mungkin merasa nyaman atau perlu untuk memanggilnya sendiri secara langsung. Sebelum Anda mulai merasa terlalu percaya diri dengan menggunakan collectTotals untuk tujuan Anda sendiri, ingatlah aturan berikut:

Produk tidak dapat ditambahkan ke kutipan setelah collectTotals dijalankan!

. . . kecuali cache item alamat kutipan dihapus.

Hampir setiap metode "kumpulkan" total model bergantung pada pengambilan item kutipan dari alamat dan mengulanginya. Pertama kali getAllItems dijalankan pada alamat kutipan, koleksi item sebenarnya di-cache dengan kunci unik, dan koleksi cache ini yang dikembalikan pada panggilan berikutnya.

Jika Anda benar-benar memiliki firasat untuk benar-benar menyelam ke kedalaman bagaimana proses pengumpulan total bekerja, Anda dapat memeriksa seri pertama dari empat bagian tentang pengumpulan total di sini untuk bacaan lebih mendalam: Mengurai koleksi Magento'sTotals: Pendahuluan

Untuk meringkas, Anda harus menangkap suatu peristiwa yang berjalan sebelum proses kumpulkan total (dan sebelum getAllItems dipanggil pada alamat kutipan) sehingga perubahan yang Anda buat pada item akan digunakan oleh total pengumpul. Saya belum memverifikasi bahwa sales_quote_collect_totals_beforeacara yang disarankan berjalan sebelum ada panggilan ke getAllItemspada alamat kutipan, tapi saya hampir yakin itu akan bekerja untuk apa yang Anda butuhkan. Tetapi jika tidak, mudah-mudahan saya telah memberikan konteks yang cukup bagi Anda untuk mencari tahu acara mana yang perlu Anda tangkap untuk membuatnya bekerja.

davidalger
sumber
Jawaban ini jauh melampaui apa yang saya harapkan. Cemerlang, terima kasih telah meluangkan waktu. Jawaban yang fantastis.
McNab
Argh! Setelah menghabiskan sepanjang hari untuk hal ini dan tidak membuatnya bekerja II akhirnya menyadari bahwa itu adalah model yang ditulis ulang di tempat lain dalam modul. Ini bekerja dengan sempurna dan saya telah belajar banyak darinya, terima kasih lagi David.
McNab
@ McNab Senang mendengar Anda berhasil. Pasti salah satu area yang lebih kompleks dari Magento yang ditangani. :)
davidalger
+1 di blog tertaut. Saya mengabaikannya beberapa kali pertama saya membacanya. Ini sangat membantu.
pspahn
6

Ada acara lain: sales_quote_item_set_productdi Mage_Sales_Model_Quote_Item :: setProduct

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

Anda dapat memodifikasi kelas pajak produk menggunakan acara ini. Gunakan metode getQty quoteItem untuk menemukan jumlah yang ditambahkan ke keranjang.

PandaWebStudio
sumber
Terima kasih untuk ini, berguna untuk mengetahui - saya menyadari berdasarkan jawaban @ davidalger bahwa saya tidak boleh memodifikasi kelas pajak produk sekarang, tetapi model penawaran. Senang tahu.
McNab
Nah, Anda benar-benar dapat memodifikasi kelas pajak item kutipan, Anda juga memiliki akses dalam acara tersebut ke objek quoteItem.
PandaWebStudio
Ah ok - saya salah paham. Terima kasih telah mengklarifikasi :)
McNab
@ PandaWebStudio, cara menetapkan jumlah pajak khusus untuk item penawaran? ini pertanyaan saya, magento.stackexchange.com/questions/274520/…
jafar pinjar
2

Mungkin mencoba mengubah kelas pajak mungkin bukan pendekatan terbaik. Mengapa tidak membuat produk serupa untuk produk-produk yang menggunakan kelas pajak yang lebih tinggi dan tentukan jumlah minimum dalam keranjang untuk produk itu. Kemudian gunakancheckout_cart_update_items_after untuk menukar produk berdasarkan jumlah total dalam keranjang?

Ini jelas bukan 'praktik terbaik' tetapi mungkin membantu Anda berpikir ke arah lain.

Atau coba atur sesuatu dengan http://www.mageworx.com/multi-fees-magento-extension.html di mana Anda menambahkan 'biaya' untuk pajak tambahan. Ini mungkin sebenarnya cara yang lebih baik untuk melakukannya tetapi tidak akan muncul dalam total pajak, lebih sebagai total baris pesanan tambahan.

Sander Mangel
sumber
Terima kasih atas balasannya Sander. Itu ide yang bagus dan saya belum memikirkannya. Saya akan memberi tahu Anda mengapa saya tidak suka itu - produk yang mendasari semua berjalan melalui UnMarketplace uMarketplace Unirgy dan merupakan tugas yang sangat berat untuk membawanya ke tempat di mana ia beroperasi sebagai situs perbandingan harga. Saya pikir itu mungkin pekerjaan besar. Jika saya tidak dapat memperbarui item kutipan ini, saya harus melihatnya.
McNab
Sial, aku bahkan tidak bisa menjawab jawaban Anda karena saya telah menghabiskan semua perwakilan saya untuk karunia ini! +1 :) Akan berubah ketika saya mendapatkan lebih banyak.
McNab
haha tidak masalah, saya mengerti masalahnya dan ini tidak akan menjadi solusi yang baik untuk kasus ini. Saya mungkin akan pergi dengan multifees, itu solusi 'bersih'
Sander Mangel
FWIW, saya tidak akan menyarankan rute ini ... jika hanya karena itu akan membuat akuntansi untuk penjualan dan pelacakan inventaris merupakan mimpi buruk yang potensial. Seperti kata OP, bukan praktik terbaik, tapi saya akan menambahkan: Ini akan menyebabkan lebih banyak masalah daripada yang akan dipecahkan.
davidalger
0

Gunakan ini <sales_quote_collect_totals_before>

dan dalam fungsi Anda suka

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

Saya harap ini akan bekerja dengan pasti

Solusi Mage2
sumber