Programáticamente añadir producto al carrito con cambio de precio


Quiero agregar un producto al carrito mediante programación. Además, quiero cambiar el precio del producto cuando se agrega al carrito.

Supongamos que el precio de mi producto es de $100. Quería cambiarlo a 9 90 cuando se agregó al carrito.

He añadido el producto al carrito. Sin embargo, no puedo cambiar el precio del producto.

Es posible?

Aquí está el código para agregar el producto al carrito: -

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

try {   
    $cart->addProduct($product, array('qty' => 1));
    $cart->save();
}
catch (Exception $ex) {
    echo $ex->getMessage();
}
 56
Author: Logan Capaldo, 2011-02-24

6 answers

Después de profundizar un poco en el código central de Magento, descubrí que necesita usar $item->getProduct()->setIsSuperMode(true) para hacer que $item->setCustomPrice() y $item->setOriginalPrice() funcionen.

Aquí hay un código de ejemplo que puede usar dentro de un Observador que escucha los eventos checkout_cart_product_add_after o checkout_cart_update_items_after. El código es lógicamente el mismo, excepto que checkout_cart_product_add_after se llama para un solo artículo y checkout_cart_update_items_after se llama para todos los artículos en el carrito. Este código se separa / duplica en 2 métodos solo como ejemplo.

Evento: 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);
    }
}

Evento: 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);
         }
    }
}
 60
Author: interimpulso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-29 21:28:58

Magento ha cambiado la forma en que se calculan los precios en el carrito, lo que hace que sea muy difícil hacer esto en v1.4 en adelante. Si establece el precio utilizando un Observador u otro dispositivo, es casi seguro que se sobrescribirá de nuevo al precio del catálogo.

Efectivamente, debe usar las reglas del carrito de compras para implementar esto.

 8
Author: Jonathan Day,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-24 12:46:37

Es posible establecer un precio específico para el cliente de un artículo de cotización. Por lo tanto, algo como esto debería hacerlo:

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

Espero que esto ayude...

 7
Author: Simon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-11 19:57:16

La respuesta de Jonathan es probablemente la mejor para la mayoría de las situaciones. Pero es posible que a algunos clientes no les guste cómo se muestran los descuentos en el carrito de compras. Recientemente hice un proyecto (con Magento 1.3.3) en el que al cliente no le gustó cómo el artículo de cada línea aún mostraba el precio completo, así como el subtotal, con una línea de Descuento debajo del subtotal: quería ver el precio de cada artículo con descuento, y el subtotal también muestra el precio con descuento. Él realmente no le gustaba tener el Línea de descuento después de la línea de Subtotal.

De todos modos, si te encuentras en el mismo barco, un enfoque es anular los métodos getCalculationPrice() y getBaseCalculationPrice() en Mage_Sales_Model_Quote_Address_Item y Mage_Sales_Model_Quote_Item. Sé que no siempre es bonito anular, mucho mejor usar eventos, pero en este caso no pude hacer que los eventos funcionen sin problemas tanto en el frontend como en el backend. No estoy seguro de si este enfoque funcionará en Magento 1.4+.

 4
Author: shaune,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-25 15:34:04

Si tengo que compartir mi solución que hice sobre la base de Simon, entonces he logrado reescribir la función de guardar clase de modelo de 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
Author: Deepak Bhatta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 09:26:32

Tuve el mismo problema y no soy desarrollador. Lo que hice fue agregar un nuevo atributo de precio en el backend de magento llamado "precio del sitio". En la página del producto esto mostró el precio más alto $100. el precio real del artículo fue de 9 90. entonces, cuando el comprador lo agrega al carrito, verá el precio real del artículo, pero en la página del producto, verá el precio del atributo personalizado de {100

Si todos sus precios en la página del producto son un conjunto % más alto que el precio real, simplemente multiplique su producto precio por el 1 por ciento. Así que si quieres añadir 10% a todos tus precios haz precio*1.1 Esto mostrará su precio como un 10% más alto, pero cuando el comprador agregue al carrito verá el precio real.

 3
Author: knowzero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-22 19:29:53