Изменить ставку налога на корзину цитату и пересчитывать

magento.stackexchange https://magento.stackexchange.com/questions/5428

  •  16-10-2019
  •  | 
  •  

Вопрос

У меня есть категория продуктов, которые (юридически) должны изменить свою налоговую ставку, когда вы заказываете больше, чем определенное количество. Я расширил различные налоговые модели, чтобы работать, когда вы добавляете новый продукт в корзину, но у меня возникают проблемы, когда пользователь обновляет количество в корзине или добавляет дополнительные продукты, которые покатывают количества, уже в корзине по порогу количество.

Проблема 1:

Прежде всего, я не на 100%, какое событие соблюдает. Я попробовал следующее;

checkout_cart_save_after (На основании этого -> https://stackoverflow.com/questions/14362702/magento-programaticaly-update-cart-via-event)

checkout_cart_update_items_after (На основании этого -> https://stackoverflow.com/questions/5104482/programmaticaly-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();

Это позволяет мне обновлять каждый пункт цитаты, когда я перехожу через (я считаю, что используя магические сеттеры, поскольку я не могу найти никаких соответствующих методов). Я надеялся иметь возможность обновить идентификатор класса налога для пункта цитаты, а затем пересматривать налоги. Если я использую следующее (где $ TaxClassID отличается от того, что уже используется каждым пунктом цитаты);

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

А затем зарегистрируйте результаты;

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

Это показывает, что я действительно обновил этот пункт цитаты и изменил налоговый идентификатор. Однако, если я тогда выполню и попытаюсь сохранить модифицированную цитату;

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

А затем снова отлаживать;

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

Мои изменения не были сохранены, изменение предмета цитаты было сброшено, и общие данные CART не пересчитаны. Начало задаваться вопросом, может ли найти высокое здание, чтобы спрыгнуть, может быть решением для этого.

Это было полезно?

Решение

Мое предложение было бы поставить наблюдателя на sales_quote_collect_totals_before событие, которое уволено в Mage_Sales_Model_Quote::collectTotals Метод до того, как он запустит общий процесс сбора. Затем изнутри этого метода наблюдателя переверните элементы цитаты и измените класс налога на (уже загруженный) объект продукта, который вы можете получить из пункта цитаты.

После того, как вы установите информацию на объекте продукта, что бы вы ни делали, не пытайтесь сохранить ее в базе данных. Установка налогового класса по мере необходимости в объекте продукта в памяти будет достаточно хорошим, чтобы найти логику итоги сбора Mage_Tax_Model_Sales_Total_Quote_Tax Пикап, на каком налоговом классе он должен основываться на расчетах. Сохранение продукта (как вы, по -видимому, пытаетесь сделать в своем примере кода выше), вызовет серьезные проблемы с производительностью, создаст условия гонки в процессе расчета и просто не является хорошей практикой.

Причина, по которой события, с которыми вы пытаетесь работать, не позволяют вам выполнить то, что вы пытаетесь достичь, заключается в том, что все они приходят после общего расчета, процесс, который будет запущен только один раз перед сохранением цитаты.

Стоит указать на процесс итоги сбора, что после запуска, не выполняя дополнительную работу, вы не можете вызвать его снова, чтобы он переиграл, основываясь на изменениях, которые вы внесли в пункты цитаты. Смотрите эту галстук, которую я взял из серии блога, мой коллега, недавно собранный в процессе Collection Totals:

Теперь, когда вы понимаете, что происходит во время процесса сбора итоги, вам может быть удобным или необходимым, чтобы назвать это непосредственно самостоятельно. Прежде чем вы начнете чувствовать себя слишком уверенно с использованием CollectTotals для ваших собственных целей, помните о следующем правиле:

Продукты не могут быть добавлены в цитату после запуска CollectTotals!

. Анкет Анкет Анкет Если кеши элементов цитаты не будут очищены.

Почти метод «Сбор» в общей модели основан на извлечении элементов цитаты с адреса и прохождением через них. В первый раз, когда GetallItems запускается по адресу цитаты, коллекция элементов на самом деле кэшируется с уникальным ключом, и именно эта кэшированная коллекция возвращается при последующих вызовах.

Если у вас есть подозревание, чтобы действительно погрузиться в глубины того, как работает процесс сбора, вы можете проверить первую из четырех частей серии «Total Collection здесь для более глубокого чтения: Раскрыть ColletTotals от Magento: введение

Подводя итог, вам необходимо поймать событие, которое работает до того, как процесс итоги сбора (и до GetallItems вызовет по адресам цитаты), так что изменения, которые вы вносите в элементы, будут использоваться общими коллекционерами. Я не подтвердил, что предлагается sales_quote_collect_totals_before событие запускается перед какими -либо звонками в getAllItems По адресу цитаты, но я почти уверен, что он будет работать для того, что вам нужно. Но если нет, надеюсь, я предоставил вам достаточно контекста, чтобы выяснить, какое событие вам нужно поймать, чтобы заставить его работать.

Другие советы

Есть еще одно событие: sales_quote_item_set_product в mage_sales_model_quote_item :: setProduct

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

Вы можете изменить класс налога на продукт, используя это событие. Используйте метод QUOTETEM GETQTY, чтобы найти QTY, добавленный в корзину.

Возможно, попытка изменить налоговый налог может быть не лучшим подходом. Почему бы не создать аналогичный продукт для тех продуктов, которые используют более высокий налоговый класс, и установить минимальный QUTY в корзине для этого продукта. Затем используйте checkout_cart_update_items_after обмениваться продуктами на основе общего количества QUTY в корзине?

Это определенно не «лучшая практика», но это может помочь вам думать в другом направлении.

В качестве альтернативы попробуйте что -нибудь настройку с http://www.mageworx.com/multi-fees-magento-extension.html где вы добавляете «плату» за дополнительный налог. На самом деле это может быть более хорошим способом сделать это, но оно не будет отображаться в налоговых итогах, в большей степени в качестве дополнительного общего порядка.

Использовать это <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);
    }
 }

Я надеюсь, что это сработает определенно

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top