59 votes

Ajouter par programme le produit au panier avec changement de prix

Je souhaite ajouter un produit au panier par programmation. De plus, je souhaite modifier le prix du produit une fois ajouté au panier.

Supposons que le prix de mon produit est de 100 $. Je voulais le changer à 90 $ une fois ajouté au panier.

J'ai ajouté le produit au panier. Cependant, je ne peux pas changer le prix du produit.

C'est possible?

Voici le code pour ajouter le produit au panier: -

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

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

63voto

interimpulso Points 489

Après avoir creusé un peu dans Magento code de base, j'ai trouvé que vous devez utiliser $item->getProduct()->setIsSuperMode(true) afin de rendre l' $item->setCustomPrice() et $item->setOriginalPrice() de travail.

Voici un exemple de code que vous pouvez utiliser à l'intérieur d'un Observateur qui est à l'écoute de l' checkout_cart_product_add_after ou checkout_cart_update_items_after événements. Le code est logiquement le même à l'exception des checkout_cart_product_add_after est appelé pour un seul élément et checkout_cart_update_items_after est appelée pour tous les articles dans le panier. Ce code est séparé/dupliqué dans 2 méthodes uniquement comme un exemple.

Événement: 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);
    }
}

Événement: 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);
         }
    }
}

8voto

Jonathan Day Points 12496

Magento a changé la façon dont les prix sont calculés dans le panier, ce qui rend très difficile cette opération à partir de la v1.4. Si vous définissez le prix à l'aide d'un observateur ou d'un autre appareil, il sera presque certainement remplacé par le prix catalogue.

Effectivement, vous devez utiliser les règles du panier pour implémenter cela.

7voto

Simon Points 1481

Il est possible de définir un prix spécifique à un client pour un article de devis. Par conséquent, quelque chose comme ceci devrait le faire:

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

J'espère que cela t'aides...

4voto

shaune Points 1329

La réponse de Jonathan est probablement le meilleur pour la plupart des situations. Mais certains clients pourraient ne pas aimer la façon dont panier des réductions sont affichés dans le panier. J'ai récemment fait un projet (avec Magento 1.3.3) où le client n'a pas comme la façon dont chaque ligne d'article encore montré le prix total ainsi que le sous-total, avec une ligne d'Escompte au-dessous de la sous - total: il voulait voir le prix de chaque article à prix réduit, et le sous-total net de la réduction de prix. Il vraiment n'aimais pas avoir le Rabais de la ligne après la ligne de sous-total.

De toute façon, si vous vous trouvez dans le même bateau, une approche consiste à remplacer la getCalculationPrice() et getBaseCalculationPrice() méthodes de Mage_Sales_Model_Quote_Address_Item et Mage_Sales_Model_Quote_Item. Je sais qu'il n'est pas toujours joli à remplacer, beaucoup mieux d'utiliser des événements, mais dans ce cas je n'arrivais pas à des événements de travailler de façon transparente sur le frontend et backend. Vous ne savez pas si cette approche fonctionne dans Magento 1.4+.

4voto

Dgent Points 129

Si je dois partager la solution que j'ai créée sur la base de Simon, je suis parvenu à réécrire la fonction de devis de la classe de modèle.

 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;
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X