Программно добавить товар в корзину с изменением цены - PullRequest
58 голосов
/ 24 февраля 2011

Я хочу добавить товар в корзину программно. Также я хочу изменить цену товара при добавлении в корзину.

Предположим, цена моего продукта составляет 100 долларов. Я хотел изменить его на 90 долларов при добавлении в корзину.

Я добавил товар в корзину. Однако я не могу изменить цену товара.

Возможно ли это?

Вот код для добавления товара в корзину: -

$cart = Mage::getSingleton('checkout/cart');

try {   
    $cart->addProduct($product, array('qty' => 1));
    $cart->save();
}
catch (Exception $ex) {
    echo $ex->getMessage();
}

Ответы [ 6 ]

62 голосов
/ 08 июня 2011

Немного покопавшись в коде ядра Magento, я обнаружил, что вам нужно использовать $item->getProduct()->setIsSuperMode(true), чтобы заставить $item->setCustomPrice() и $item->setOriginalPrice() работать.

Вот пример кода, который вы можете использовать в Обозревателе, который прослушивает события checkout_cart_product_add_after или checkout_cart_update_items_after. Код логически тот же, за исключением того, что checkout_cart_product_add_after вызывается только для одного товара, а checkout_cart_update_items_after вызывается для всех товаров в корзине. Этот код разделен / дублирован на 2 метода только в качестве примера.

Событие: checkout_cart_product_add_after

/**
 * @param Varien_Event_Observer $observer
 */
public function applyDiscount(Varien_Event_Observer $observer)
{
    /* @var $item Mage_Sales_Model_Quote_Item */
    $item = $observer->getQuoteItem();
    if ($item->getParentItem()) {
        $item = $item->getParentItem();
    }

    // Discounted 25% off
    $percentDiscount = 0.25; 

    // This makes sure the discount isn't applied over and over when refreshing
    $specialPrice = $item->getOriginalPrice() - ($item->getOriginalPrice() * $percentDiscount);

    // Make sure we don't have a negative
    if ($specialPrice > 0) {
        $item->setCustomPrice($specialPrice);
        $item->setOriginalCustomPrice($specialPrice);
        $item->getProduct()->setIsSuperMode(true);
    }
}

Событие: checkout_cart_update_items_after

/**
 * @param Varien_Event_Observer $observer
 */
public function applyDiscounts(Varien_Event_Observer $observer)
{
    foreach ($observer->getCart()->getQuote()->getAllVisibleItems() as $item /* @var $item Mage_Sales_Model_Quote_Item */) {
         if ($item->getParentItem()) {
             $item = $item->getParentItem();
         }

         // Discounted 25% off
         $percentDiscount = 0.25; 

         // This makes sure the discount isn't applied over and over when refreshing
         $specialPrice = $item->getOriginalPrice() - ($item->getOriginalPrice() * $percentDiscount);

         // Make sure we don't have a negative
         if ($specialPrice > 0) {
             $item->setCustomPrice($specialPrice);
             $item->setOriginalCustomPrice($specialPrice);
             $item->getProduct()->setIsSuperMode(true);
         }
    }
}
8 голосов
/ 24 февраля 2011

Magento изменил способ расчета цены в корзине, что делает это очень трудным в v1.4 и далее.Если вы установите цену с помощью Обозревателя или другого устройства, она почти наверняка будет перезаписана обратно в цену каталога.

По сути, вам нужно использовать правила Корзины, чтобы реализовать это.

7 голосов
/ 11 июля 2011

Можно установить конкретную цену для клиента. Следовательно, что-то вроде этого должно сделать это:

$quoteItem = $quote->addProduct($product, $qty);
$quoteItem->setCustomPrice($price);
// we need this since Magento 1.4
$quoteItem->setOriginalCustomPrice($price);
$quote->save();

Надеюсь, это поможет ...

4 голосов
/ 01 ноября 2011

Если мне нужно поделиться своим решением, которое я принял на основе Simon, то мне удалось переписать функцию сохранения класса quote для цитаты.

public function save()
{

    $this->getQuote()->getBillingAddress();
    $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
    $this->getQuote()->collectTotals();
    //$this->getQuote()->save();

    foreach($this->getQuote()->getAllItems() as $item) {             
          $productId = $item->getProductId();
          $product = Mage::getModel('catalog/product')->load($productId);
          if($product->getAttributeText('is_dummy') == 'Yes') {
            $price = 2;
            $item->setCustomPrice($price);
            // we need this since Magento 1.4
            $item->setOriginalCustomPrice($price);
          }
    }  
       $this->getQuote()->save();   
    $this->getCheckoutSession()->setQuoteId($this->getQuote()->getId());
    /**
     * Cart save usually called after chenges with cart items.
     */
    Mage::dispatchEvent('checkout_cart_save_after', array('cart'=>$this));
    return $this;
}
4 голосов
/ 25 февраля 2011

Ответ Джонатана, вероятно, лучший для большинства ситуаций.Но некоторым покупателям может не понравиться, как в корзине отображаются скидки в корзине.Недавно я сделал проект (с Magento 1.3.3), в котором клиенту не понравилось, как каждая позиция все еще показывает полную цену, а также промежуточный итог, со строкой скидки ниже промежуточного итога - он хотел увидеть ценукаждый предмет со скидкой, а промежуточный итог показывает также скидочную цену.Ему на самом деле не понравилось, когда после строки промежуточных итогов есть строка "Скидка".

В любом случае, если вы окажетесь в одной лодке, один из подходов - переопределить getCalculationPrice () и getBaseCalculationPrice () методы в Mage_Sales_Model_Quote_Address_Item и Mage_Sales_Model_Quote_Item.Я знаю, что не всегда приятно переопределять, гораздо лучше использовать события, но в этом случае я не мог заставить события работать без проблем как на внешнем интерфейсе, так и на внутреннем.Не уверен, что этот подход будет работать в Magento 1.4 +.

3 голосов
/ 22 ноября 2012

У меня была такая же проблема, и я не разработчик.То, что я сделал, добавило новый ценовой атрибут в бэкэнд magento под названием «цена сайта».На странице товара это показало более высокую цену 100 долларов.Фактическая цена товара составляла 90 долларов.поэтому, когда покупатель добавляет его в корзину, он увидит фактическую цену товара, но на странице товара он увидит цену пользовательского атрибута в размере 100

, если все ваши цены на странице товара будут на% вышетогда реальная цена просто умножьте цену вашего продукта на 1 + процент.Поэтому, если вы хотите добавить 10% ко всем вашим ценам, сделайте цену * 1.1. Эта цена будет отображаться на 10% выше, но когда покупатель добавит в корзину, он увидит реальную цену.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...