У меня есть категория продуктов, для которых (по закону) необходимо изменить налоговую ставку, когда вы заказываете больше определенного количества. Я расширил различные налоговые модели, чтобы это работало, когда вы добавляете новый продукт в корзину, но у меня возникают проблемы, когда пользователь обновляет количества в корзине или добавляет дополнительные продукты, которые превышают пороговое значение, уже находящееся в корзине. количество.
Проблема 1:
Прежде всего, я не на 100% какое событие (я) наблюдаю. Я пробовал следующее;
checkout_cart_save_after
(на основании этого -> https://stackoverflow.com/questions/14362702/magento-programatics-update-cart-via-event )
checkout_cart_update_items_after
(на основании этого -> https://stackoverflow.com/questions/5104482/programmatics-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);
Мои изменения не были сохранены, изменение позиции котировки было сброшено, а итоги корзины не были пересчитаны. Начинаю задумываться, может ли решение этой проблемы найти высокое здание, с которого можно спрыгнуть.
источник
Ответы:
Мое предложение состояло бы в том, чтобы назначить наблюдателя на
sales_quote_collect_totals_before
событие, которое запускается вMage_Sales_Model_Quote::collectTotals
методе, прежде чем он начнет общий процесс сбора. Затем внутри этого метода наблюдателя выполните итерацию элементов предложения и измените класс налога для (уже загруженного) объекта продукта, который вы можете извлечь из элемента предложения.После того, как вы установите информацию об объекте продукта, что бы вы ни делали, НЕ пытайтесь сохранить ее в базе данных. Устанавливая необходимый класс налога для объекта продукта в памяти, будет достаточно, чтобы в
Mage_Tax_Model_Sales_Total_Quote_Tax
пикапе была обнаружена логика сбора итогов, на каком классе налога он должен основывать свои вычисления. Сохранение продукта (как вы, похоже, пытаетесь это сделать в приведенном выше примере кода) вызовет серьезные проблемы с производительностью, создаст условия гонки в процессе вычислений и просто не является хорошей практикой.Причина, по которой события, с которыми вы пытаетесь работать, не позволяют вам выполнить то, что вы пытаетесь выполнить, состоят в том, что все они следуют после общего расчета, процесс, который запускается только один раз до сохранения предложения.
Стоит отметить, что процесс сбора итогов заключается в том, что после запуска, не выполняя дополнительную работу, вы не сможете вызывать его снова, чтобы выполнить его пересчет на основе изменений, внесенных вами в элементы предложения. Посмотрите на эту связку, которую я взял из серии блогов, недавно созданной моим коллегой по процессу сбора итогов:
Если у вас есть подсказка для того, чтобы по-настоящему погрузиться в глубины того, как работает процесс сбора итогов, вы можете ознакомиться с первой из четырех серий статей по сбору итогов здесь для более подробного прочтения: Раскрытие коллекций Magento сборник: Введение
Подводя итог, вам нужно перехватить событие, которое запускается до процесса сбора итогов (и до вызова getAllItems по адресам котировок), чтобы изменения, которые вы вносите в элементы, использовались сборщиками итогов. Я не проверял, что предлагаемое
sales_quote_collect_totals_before
событие запускается перед любыми вызовамиgetAllItems
по указанному адресу, но я почти уверен, что оно будет работать для того, что вам нужно. Но если нет, надеюсь, я предоставил вам достаточно контекста, чтобы выяснить, какое событие вам нужно отловить, чтобы оно заработало.источник
Есть еще одно событие:
sales_quote_item_set_product
в Mage_Sales_Model_Quote_Item :: setProductВы можете изменить класс налога на продукт, используя это событие. Используйте метод quoteItem getQty, чтобы найти кол-во, добавленное в корзину.
источник
Возможно, попытка изменить налоговый класс может оказаться не лучшим подходом. Почему бы не создать аналогичный продукт для тех продуктов, которые используют более высокий налоговый класс и установить минимальное количество в корзине для этого продукта. Затем использовать,
checkout_cart_update_items_after
чтобы обменять продукты на основе общего количества в корзине?Это определенно не «лучшая практика», но она может помочь вам мыслить в другом направлении.
В качестве альтернативы попробуйте настроить что-нибудь с http://www.mageworx.com/multi-fees-magento-extension.html, где вы добавляете «плату» за дополнительный налог. На самом деле это может быть более хороший способ сделать это, но он не будет отображаться в итоговых суммах налога, а скорее в виде строки итогового дополнительного заказа.
источник
Использовать этот
<sales_quote_collect_totals_before>
и в твоих функциях нравится
Я надеюсь, что это будет работать определенно
источник