Sửa đổi thuế suất đối với các mặt hàng báo giá giỏ hàng và tính toán lại


31

Tôi có một danh mục sản phẩm (về mặt pháp lý) cần phải thay đổi thuế suất khi bạn đặt hàng nhiều hơn một số lượng nhất định. Tôi đã mở rộng các mô hình thuế khác nhau để hoạt động này khi bạn thêm một sản phẩm mới vào giỏ hàng, nhưng tôi gặp vấn đề khi người dùng cập nhật số lượng trong giỏ hàng hoặc thêm các sản phẩm bổ sung có số lượng trong giỏ hàng vượt quá ngưỡng số lượng.

Vấn đề 1:

Trước hết, tôi không quan sát 100% sự kiện nào. Tôi đã thử như sau;

checkout_cart_save_after(dựa trên điều này -> https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event )

checkout_cart_update_items_after(dựa trên điều này -> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )

sales_quote_save_before(dựa trên điều này -> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )

Vấn đề 2:

Tôi có thể truy cập các mục báo giá từ giỏ hàng, có rất nhiều cách để làm điều đó dường như. Tôi cũng có thể lặp qua các mục riêng lẻ trong giỏ hàng, cập nhật thuộc tính của các mục đó và sau đó lưu các mục (ít nhất là tạm thời). Tuy nhiên, sau đó tôi không thể lưu báo giá và tính toán lại các khoản thuế trong thanh toán.

Một phần lý do là trong khi tôi có thể truy cập vào báo giá giỏ hàng, tôi không chắc nên sử dụng phương pháp nào để có thể viết cho nó.

Những gì tôi đã thử:

Những gì tôi đã thử về việc truy cập nội dung của giỏ hàng phụ thuộc vào sự kiện tôi đã quan sát nhưng tôi đã thử tất cả những điều sau đây;

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

Cái mà dường như ít nhất cho phép tôi truy cập vào trích dẫn, chạy qua chúng và cập nhật các mục là

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

Điều này cho phép tôi cập nhật từng mục trích dẫn khi tôi lặp lại (Tôi tin rằng sử dụng ma thuật khi tôi không thể tìm thấy bất kỳ phương pháp tương ứng nào). Tôi đã hy vọng có thể cập nhật ID Nhóm thuế cho mục báo giá và sau đó tính toán lại các loại thuế. Nếu tôi sử dụng như sau (trong đó $ taxClassId khác với mục đã được sử dụng bởi mỗi mục trích dẫn);

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

Và sau đó đăng nhập kết quả;

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

Nó cho thấy rằng tôi thực sự đã cập nhật mục báo giá này và thay đổi ID thuế. Tuy nhiên, nếu sau đó tôi làm theo và cố gắng lưu trích dẫn đã sửa đổi;

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

Và sau đó gỡ lỗi một lần nữa;

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

Thay đổi của tôi chưa được lưu, thay đổi mục báo giá đã được đặt lại và tổng số giỏ hàng không được tính toán lại. Bắt đầu tự hỏi nếu tìm một tòa nhà cao tầng để nhảy xuống có thể là giải pháp cho cái này.


xin mọi người giúp tôi giải quyết việc này: stackoverflow.com/questions/27978781/ cảm ơn bạn.
satish

Câu trả lời:


35

Đề nghị của tôi sẽ là đưa một người quan sát vào sales_quote_collect_totals_beforesự kiện được bắn trong Mage_Sales_Model_Quote::collectTotalsphương thức trước khi nó bắt đầu quá trình thu thập tổng thể. Sau đó, từ bên trong phương thức quan sát này, lặp lại các mục trích dẫn và thay đổi lớp thuế trên đối tượng sản phẩm (đã được tải) mà bạn có thể truy xuất từ ​​mục trích dẫn.

Sau khi bạn đặt thông tin về đối tượng sản phẩm, bất kể bạn làm gì, KHÔNG thử và lưu nó vào cơ sở dữ liệu. Có lớp thuế được đặt khi cần thiết cho đối tượng sản phẩm trong bộ nhớ sẽ đủ tốt để có logic tổng hợp thu thập được tìm thấy trong phần Mage_Tax_Model_Sales_Total_Quote_Taxthu mà loại thuế cần dựa trên tính toán của nó. Việc lưu sản phẩm (như bạn dường như đang cố gắng thực hiện trong mẫu mã của mình ở trên) sẽ gây ra các vấn đề hiệu suất lớn, sẽ tạo ra các điều kiện chủng tộc trong quy trình tính toán và đơn giản là không thực hành tốt.

Lý do mà các sự kiện bạn đang cố gắng xử lý không cho phép bạn hoàn thành những gì bạn đang cố gắng thực hiện là vì tất cả đều diễn ra sau khi tính toán tổng thể, một quá trình chỉ được thực hiện một lần trước khi lưu báo giá.

Đáng chú ý về quy trình tổng hợp thu thập là một khi chạy, mà không phải làm thêm, bạn không thể gọi lại để tính toán lại dựa trên những thay đổi bạn đã thực hiện đối với các mục trích dẫn. Xem tie-bit này tôi đã lấy từ loạt blog một tập hợp của tôi gần đây được đưa vào quy trình tổng hợp thu thập:

Bây giờ bạn đã hiểu những gì xảy ra trong quá trình thu thập tổng số, bạn có thể thấy thuận tiện hoặc cần thiết để gọi trực tiếp cho mình. Tuy nhiên, trước khi bạn bắt đầu cảm thấy quá tự tin với việc sử dụng collTotals cho mục đích riêng của mình, hãy ghi nhớ quy tắc sau:

Sản phẩm không thể được thêm vào báo giá sau khi collTotals được chạy!

. . . trừ khi bộ nhớ cache của địa chỉ trích dẫn bị xóa.

Gần như mọi phương pháp "thu thập" của mọi mô hình đều phụ thuộc vào việc tìm nạp các mục trích dẫn từ địa chỉ và lặp qua chúng. Lần đầu tiên getAllItems được chạy trên một địa chỉ báo giá, bộ sưu tập vật phẩm thực sự được lưu trong bộ nhớ cache với một khóa duy nhất và đó là bộ sưu tập được lưu trong bộ nhớ cache này được trả về trong các cuộc gọi tiếp theo.

Nếu bạn thực sự có một ý tưởng mơ hồ để thực sự tìm hiểu sâu về cách thức hoạt động của quy trình tổng hợp thu thập, bạn có thể xem phần đầu tiên của loạt bốn phần về tổng bộ sưu tập ở đây để đọc sâu hơn: Làm sáng tỏ bộ sưu tập của MagentoTotals: Giới thiệu

Để tóm tắt, bạn cần bắt một sự kiện diễn ra trước quá trình thu thập tổng số (và trước khi getAllItems được gọi trên địa chỉ báo giá) để những thay đổi bạn thực hiện đối với các mục sẽ được sử dụng bởi các nhà sưu tập. Tôi đã không xác minh rằng sales_quote_collect_totals_beforesự kiện được đề xuất chạy trước bất kỳ cuộc gọi nào đến getAllItemsđịa chỉ báo giá, nhưng tôi gần như chắc chắn rằng nó sẽ hoạt động cho những gì bạn cần. Nhưng nếu không, hy vọng tôi đã cung cấp đủ bối cảnh để bạn tìm ra sự kiện nào bạn cần nắm bắt để làm cho nó hoạt động.


Câu trả lời này vượt xa những gì tôi hy vọng. Rực rỡ, cảm ơn vì đã dành thời gian. Câu trả lời tuyệt vời.
McNab

Argh! Sau khi dành cả ngày cho việc này và không làm cho nó hoạt động, cuối cùng tôi nhận ra rằng đó là một mô hình được viết lại tồi ở nơi khác trong mô-đun. Điều này hoạt động hoàn hảo và tôi đã học được tải từ nó, cảm ơn một lần nữa David.
McNab

@McNab Rất vui khi biết bạn đã làm việc. Chắc chắn là một trong những lĩnh vực phức tạp hơn của Magento đang bị xử lý. :)
davidalger

+1 trên blog được liên kết. Tôi đã bỏ qua nó vài lần đầu tiên tôi đọc qua. Đó là một sự giúp đỡ lớn.
pspahn

6

Có một sự kiện khác: sales_quote_item_set_producttrong Mage_Sales_Model_Quote_Item :: set sản phẩm

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

Bạn có thể sửa đổi lớp thuế sản phẩm bằng cách sử dụng sự kiện này. Sử dụng phương thức quoteItem getQty để tìm qty được thêm vào giỏ hàng.


Cảm ơn vì điều này, rất hữu ích khi biết - Tôi nhận ra dựa trên câu trả lời của @ davidalger rằng tôi không nên sửa đổi loại thuế của sản phẩm ngay bây giờ, mà là mô hình báo giá. Tốt để biết mặc dù.
McNab

Vâng, bạn thực sự có thể sửa đổi lớp thuế mục trích dẫn, bạn cũng có quyền truy cập trong sự kiện vào đối tượng quoteItem.
PandaWebStudio

À ok - tôi hiểu lầm. Cảm ơn đã làm rõ :)
McNab

@PandaWebStudio, làm cách nào để đặt số tiền thuế tùy chỉnh cho mục báo giá? đây là câu hỏi của tôi, magento.stackexchange.com/questions/274520/ Kẻ
jafar pinjar

2

Có lẽ cố gắng thay đổi lớp thuế có thể không phải là cách tiếp cận tốt nhất. Tại sao không tạo ra một sản phẩm tương tự cho những sản phẩm sử dụng loại thuế cao hơn và đặt số lượng tối thiểu trong giỏ hàng cho sản phẩm đó. Sau đó sử dụng checkout_cart_update_items_afterđể trao đổi sản phẩm xung quanh dựa trên tổng số qty trong giỏ hàng?

Đây chắc chắn không phải là một 'cách thực hành tốt nhất' nhưng nó có thể giúp bạn suy nghĩ theo hướng khác.

Ngoài ra, hãy thử thiết lập một cái gì đó với http://www.mageworx.com/multi-fees-magento-extension.html nơi bạn thêm 'phí' cho thuế thêm. Đây thực sự có thể là một cách tốt hơn để làm điều đó nhưng nó sẽ không hiển thị trong tổng số thuế, nhiều hơn là một dòng tổng đơn đặt hàng thêm.


Cảm ơn đã trả lời Sander. Đó là một ý tưởng tốt và tôi đã không nghĩ về nó. Tôi sẽ cho bạn biết lý do tại sao tôi không thích điều đó - tất cả các sản phẩm cơ bản đều đang chạy mặc dù bộ uMarketplace của Unirgy và đó là một nhiệm vụ khó khăn để đưa nó đến nơi mà nó đang chạy như một trang web so sánh giá. Tôi nghĩ rằng đó có thể là một công việc lớn. Nếu tôi không thể cập nhật mục báo giá này, tôi sẽ phải xem xét nó.
McNab

Chết tiệt, tôi thậm chí không thể đưa ra câu trả lời của bạn vì tôi đã dành tất cả đại diện của mình cho tiền thưởng này! +1 :) Sẽ nâng cấp khi tôi nhận được thêm.
McNab

haha không có vấn đề gì, tôi hiểu vấn đề và đây sẽ không phải là một giải pháp tốt cho vụ án. Có lẽ tôi sẽ đi cùng với nhiều người sau đó, đó là một giải pháp 'sạch hơn'
Sander Mangel

FWIW, tôi sẽ không đề xuất lộ trình này nếu chỉ vì nó sẽ khiến kế toán bán hàng và theo dõi hàng tồn kho trở thành một cơn ác mộng tiềm năng. Như OP đã nói, không phải cách thực hành tốt nhất, nhưng tôi sẽ nói thêm: Nó sẽ gây ra nhiều rắc rối hơn nó sẽ giải quyết.
davidalger

0

Dùng cái này <sales_quote_collect_totals_before>

và trong chức năng của bạn làm như thế nào

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

Tôi hy vọng điều này sẽ làm việc chắc chắn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.