Добавляйте товары в заказ программно, чтобы модуль оплаты их видел
Я создаю расширение, которое добавляет ряд товаров в заказ, как только пользователь нажимает "оформить заказ" (после ввода всех их деталей).
Я использую наблюдателя событий sales_order_place_before
Я добавляю элементы в Mage::getModel ('продажи/quote_item') и Mage::getModel('продажи/заказ_item')
Элементы отображаются в правильном порядке во внешнем и внутреннем интерфейсе.
Однако платежный модуль Я использую (eWay Rapid), не вижу новых предметов. Я подтвердил это, включив отладку расширения, где оно выводит элементы в обрабатываемом заказе, моих добавленных элементов ТАМ НЕТ. Я также подтвердил, что мое расширение добавляет товары ДО того, как платежный модуль вступит во владение.
Я не думаю, что это будет только этот платежный модуль, я думаю, что это связано с тем, как ядро Magento работает с любым платежным модулем, когда он передает детали заказа.
Как я могу добавить элементы в заказ и имейте в виду платежный модуль?
2 answers
Ваша проблема, вероятно, связана с элементами, кэшируемыми в методе getAllItems
public function getAllItems()
{
// We calculate item list once and cache it in three arrays - all items, nominal, non-nominal
$cachedItems = $this->_nominalOnly ? 'nominal' : ($this->_nominalOnly === false ? 'nonnominal' : 'all');
$key = 'cached_items_' . $cachedItems;
if (!$this->hasData($key)) {
Методы добавления в Magento не делают этот кэш недействительным. Поэтому что-то вроде $address->unsetData('cached_items_all');
может сработать после того, как вы добавите свой продукт.
Я не выполнил добавление товаров в заказ (после этапа оформления заказа) и не уведомил о них платежный модуль.
Как указано в ответе Фумана, это, скорее всего, было вызвано тем, что результат getAllItems был кэширован до того, как я добавил элементы в заказ.
Вероятно, это был ПЛОХОЙ способ выполнить задачу в любом случае, добавление товаров в заказ после того, как клиент завершил оформление заказа, просто кажется безвкусным. Я думал, что это единственный выход, но мне удалось чтобы добавить товары в корзину и переопределить их стандартные цены, как я пытался сделать.
Хитрость заключалась в том, чтобы использовать наблюдателя checkout_cart_product_add_after и установить флаги на объекте цитаты, чтобы я знал, что происходит в следующий раз, когда наблюдатель выстрелит.
Вот пример способа добавления идентификатора продукта 101 с пользовательской ценой в корзину, когда клиент покупает идентификатор продукта 100. Я надеюсь, что это кому-то поможет.
public function checkout_cart_product_add_after(Varien_Event_Observer $observer) {
$this->log('Observer: checkout_cart_product_add_after');
$cart = Mage::getModel('checkout/cart');
$cart->init();
$quoteItem = $observer->getQuoteItem();
$quote = $quoteItem->getQuote();
$my_flag = $quote->getMyFlag(); // Grab the flag, if it's been set yet
if($my_flag == "adding bonus") {
// If we're here we know that this time the observer was fired after we added our bonus product to the cart
$my_price = $quote->getMyPrice(); // Get the price that was set last time the observer fired
$quoteItem->setIsSuperMode(true); // You need to set this to override a product price
$quoteItem->setCustomPrice($my_price); // Set your override price here
$quoteItem->setOriginalCustomPrice($my_price); // And here
$quoteItem->save(); // Save the item so the new price will stick in the cart
} else {
// If we're here we are processing/observing a normal "add to cart"
if($quoteItem->getProduct()->getId() == "100") { // Check if the product being added is the ID we want to add a bonus for
$quote->setMyFlag("adding bonus"); // This is how we'll know the next time the observer fires that we need to override the price
$quote->setMyBonusPrice(5.00); // Here is a way you can store the price you want to override it to (we'll grab this value next time the observer fires)
$bonusItem = Mage::getModel('catalog/product')->load("101"); // load the bonus product
$params = array(
'product' => "101",
'qty' => "1"
);
$cartItem = $cart->addProduct($bonusItem,$params); //Add it to the cart - this will fire the observer again... but this time with the flags we set earlier.
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
}
}
}