장바구니 견적 품목의 세율을 수정하고 다시 계산


31

특정 수량을 초과하여 주문할 때 (법적으로) 세금율을 변경해야하는 제품 범주가 있습니다. 장바구니에 새 제품을 추가 할 때이 작업을 수행하기 위해 다양한 세금 모델을 확장했지만 사용자가 장바구니의 수량을 업데이트하거나 이미 장바구니에있는 수량을 임계 값을 초과하는 추가 제품을 추가 할 때 문제가 있습니다 양.

문제 1 :

우선, 나는 어떤 사건을 관찰 해야하는지 100 %가 아닙니다. 나는 다음을 시도했다.

checkout_cart_save_after(이에 따라-> https://stackoverflow.com/questions/14362702/magento-programatically-update-cart-via-event )

checkout_cart_update_items_after(이에 따라-> https://stackoverflow.com/questions/5104482/programmatically-add-product-to-cart-with-price-change )

sales_quote_save_before(이에 따라-> https://stackoverflow.com/questions/7638858/magento-recalculate-cart-total-in-observer )

문제 2 :

장바구니에서 견적 항목에 액세스 할 수 있는데 그렇게하는 방법이 많이 있습니다. 또한 장바구니의 개별 항목을 반복하고 해당 항목의 속성을 업데이트 한 다음 항목을 저장할 수 있습니다 (적어도 일시적으로). 그러나 견적을 저장하고 결제시 세금을 다시 계산할 수 없습니다.

그 이유 중 일부는 장바구니 견적에 액세스 할 수 있지만 어떤 방법으로 쓸 수 있는지 잘 모르겠습니다.

내가 시도한 것 :

장바구니의 내용에 액세스하는 데있어 시도한 것은 내가 관찰 한 이벤트에 따라 다르지만 다음을 모두 시도했습니다.

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

적어도 견적에 액세스하고 견적을 실행하고 항목을 업데이트 할 수있는 것으로 보입니다.

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

이렇게하면 반복 할 때 각 견적 항목을 업데이트 할 수 있습니다 (해당하는 방법을 찾을 수 없으므로 마술 설정기를 사용한다고 생각합니다). 견적 항목의 세금 클래스 ID를 업데이트 한 다음 세금을 다시 계산할 수 있기를 바랐습니다. 다음을 사용하면 ($ taxClassId가 각 견적 항목에서 이미 사용한 것과 다릅니다);

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

그런 다음 결과를 기록하십시오.

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

실제로이 견적 항목을 업데이트하고 세금 ID를 변경했음을 나타냅니다. 그러나 그런 다음 수정하여 견적을 저장하려고합니다.

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

그런 다음 다시 디버그하십시오.

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

변경 사항이 저장되지 않고 견적 항목 변경이 재설정되었으며 장바구니 총계가 다시 계산되지 않습니다. 고층 빌딩을 찾는 것이이 솔루션의 해결책인지 궁금해지기 시작했습니다.


아무도이 문제를 해결하도록 도와주세요 : stackoverflow.com/questions/27978781/… 감사합니다.
satish

답변:


35

내 제안은 총 수집 프로세스를 시작하기 전에 메서드 sales_quote_collect_totals_before에서 Mage_Sales_Model_Quote::collectTotals시작된 이벤트에 관찰자를 배치하는 것 입니다. 그런 다음이 옵저버 메소드 내부에서 견적 항목을 반복하고 견적 항목에서 검색 할 수있는 (이미로드 된) 제품 오브젝트의 세금 클래스를 변경하십시오.

제품 오브젝트에 대한 정보를 설정 한 후에는 수행하지 말고 데이터베이스에 저장하지 마십시오. 메모리의 제품 오브젝트에 필요한 세금 클래스를 설정하면 Mage_Tax_Model_Sales_Total_Quote_Tax계산에서 계산해야 할 세금 클래스의 픽업 에서 총계 수집 논리를 찾을 수 있을 것입니다. 제품을 저장하면 (위의 코드 샘플에서 시도한 것처럼) 중대한 성능 문제가 발생하고 계산 프로세스에서 경쟁 조건이 발생하며 단순히 좋은 습관이 아닙니다.

작업하려는 이벤트로 인해 달성하려는 작업을 수행 할 수없는 이유는 모두 견적을 저장하기 전에 한 번만 실행되는 프로세스 인 전체 계산을 수행하기 때문입니다.

총계 수집 프로세스에 대해 지적 할 가치가있는 것은 추가 작업을 수행하지 않고 한 번 실행 한 후에는 견적 항목의 변경 사항에 따라 다시 계산하도록 다시 호출 할 수 없다는 것입니다. 블로그 시리즈에서 가져온이 타이 비트를 참조하십시오. 최근에 총계 수집 프로세스에 결합한 광산이 있습니다.

총계 수집 프로세스 중에 발생하는 사항을 이해 했으므로 직접 직접 호출하는 것이 편리하거나 필요할 수 있습니다. 그러나 자신의 목적으로 collectTotals를 사용하는 것에 너무 자신감이 생기기 전에 다음 규칙을 명심하십시오.

collectTotals가 실행 된 후 견적에 제품을 추가 할 수 없습니다!

. . . 견적 주소의 항목 캐시가 지워지지 않는 한.

거의 모든 총 모델의 "collect"메소드는 주소에서 견적 항목을 가져 와서 루핑하는 데 의존합니다. getAllItems가 처음으로 견적 주소에서 실행될 때 항목 콜렉션은 실제로 고유 키로 캐시되며 후속 호출에서 리턴되는이 캐시 된 콜렉션입니다.

총계 수집 프로세스가 작동하는 방식의 깊이를 실제로 이해하기 위해 잉크가 발생하는 경우 자세한 내용을 보려면 여기에서 총 콜렉션에 대한 네 가지 파트 시리즈 중 첫 번째 시리즈를 확인하십시오 .

요약하면, 총계 수집 프로세스에서 항목의 변경 사항이 사용되도록 총계 수집 프로세스 전에 (및 견적 주소에서 getAllItems가 호출되기 전에) 실행되는 이벤트를 포착해야합니다. 따옴표 주소를 sales_quote_collect_totals_before호출하기 전에 제안 된 이벤트가 실행 getAllItems되는지 확인하지는 않았지만 필요한 이벤트 에 적합하다고 확신합니다. 그러나 그렇지 않다면, 나는 그것이 당신이 이벤트를 작동시키기 위해 잡을 필요가있는 이벤트를 알아낼 수있는 충분한 컨텍스트를 제공했습니다.


이 답변은 내가 기대했던 것 이상입니다. 시간 내 주셔서 감사합니다. 환상적인 답변.
McNab

아아! 하루 종일 이것을 보내고 작동시키지 않으면 II는 모듈의 다른 곳에서 잘못 작성된 모델로 전환되었다는 것을 마침내 깨달았습니다. 이것은 완벽하게 작동하며 David로부터 다시 한 번 배웠습니다.
McNab

@McNab 기쁘다. 다행이다. 마젠 토의 더 복잡한 영역 중 하나는 확실히 다루어지고 있습니다. :)
davidalger

링크 된 블로그에서 +1 처음 몇 번 읽었을 때 그것을 간과했습니다. 큰 도움이됩니다.
pspahn

6

sales_quote_item_set_productMage_Sales_Model_Quote_Item :: setProduct에 다른 이벤트가 있습니다.

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

이 이벤트를 사용하여 제품 세금 클래스를 수정할 수 있습니다. quoteItem getQty 메소드를 사용하여 장바구니에 추가 된 수량을 찾으십시오.


이 사실에 감사드립니다. 알아두면 도움이됩니다. @davidalger의 답변을 바탕으로 지금 제품의 세금 등급을 수정하지 말고 견적 모델을 수정해야한다는 것을 알고 있습니다. 그래도 반갑습니다.
McNab

실제로 견적 항목 세금 클래스를 수정할 수 있으며, 이벤트에서 quoteItem 객체에 액세스 할 수도 있습니다.
PandaWebStudio

아 알았어-오해 했어 설명해 주셔서 감사합니다 :)
McNab

@PandaWebStudio, 견적 품목에 대한 사용자 정의 세금 금액을 설정하는 방법은 무엇입니까? 여기 내 질문 magento.stackexchange.com/questions/274520/…
jafar pinjar

2

세금 클래스를 변경하려고 시도하는 것이 최선의 방법이 아닐 수도 있습니다. 더 높은 세금 등급을 사용하는 제품에 대해 유사한 제품을 만들고 해당 제품의 장바구니에 최소 수량을 설정하십시오. 그런 다음 checkout_cart_update_items_after장바구니의 총 수량을 기준으로 제품을 교체 하려면 ?

이것은 반드시 '모범 사례'는 아니지만 다른 방향으로 생각하는 데 도움이 될 수 있습니다.

또는 추가 세금에 '수수료'를 추가하는 http://www.mageworx.com/multi-fees-magento-extension.html을 사용하여 무언가를 설정 하십시오 . 실제로이 방법을 사용하는 것이 좋지만 세금 합계에는 추가 주문 총계로 표시되지 않습니다.


답장을 보내 주셔서 감사합니다. 좋은 생각이었고 나는 그것을 생각하지 않았다. 내가 기쁘지 않은 이유를 알려줄 것입니다-Unirgy의 uMarketplace 제품군을 통해 기본 제품이 모두 실행 중이며 가격 비교 사이트로 실행되는 곳으로 가져 오는 작업의 괴물이었습니다. 나는 그것이 큰 일이라고 생각합니다. 이 견적 항목을 업데이트 할 수 없으면 그래도 살펴 봐야합니다.
McNab

젠장, 나는이 현상금에 대한 모든 담당자를 보냈으므로 당신의 대답을 찬성조차 할 수 없습니다! +1 :) 더 얻을 때 공감할 것입니다.
McNab

하하 아무 문제 없습니다, 나는 문제를 이해하고 이것은 좋은 해결책이 아닐 것입니다. 아마 아마 multifees와 함께 갈 것입니다, 그것은 '깨끗한'솔루션입니다
Sander Mangel

FWIW, 나는이 경로를 제안하지 않을 것입니다 ... 판매를 설명하고 재고를 추적하는 것이 악몽이 될 수 있기 때문입니다. OP가 말했듯이 모범 사례는 아니지만 추가 할 것입니다 : 해결하는 것보다 많은 문제가 발생합니다.
davidalger

0

이것을 사용하십시오 <sales_quote_collect_totals_before>

그리고 당신의 기능 에서처럼

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

나는 이것이 분명히 작동하기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.