web-dev-qa-db-fra.com

Ajouter par programme le produit au panier avec changement de prix

Je souhaite ajouter un produit au panier par programme. Je souhaite également modifier le prix du produit une fois ajouté au panier.

Supposons que le prix de mon produit soit de 100 $. Je voulais le changer à 90 $ lors de l'ajout au panier.

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

C'est possible?

Voici le code pour ajouter un produit au panier: -

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

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

Après avoir creusé un peu dans le code de base de Magento, j'ai constaté que vous devez utiliser $item->getProduct()->setIsSuperMode(true) pour faire fonctionner $item->setCustomPrice() et $item->setOriginalPrice().

Voici un exemple de code que vous pouvez utiliser dans un observateur qui écoute le checkout_cart_product_add_after ou checkout_cart_update_items_after événements. Le code est logiquement le même sauf checkout_cart_product_add_after est appelé pour un seul élément et checkout_cart_update_items_after est appelé pour tous les articles du panier. Ce code est séparé/dupliqué en 2 méthodes uniquement à titre d'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);
         }
    }
}
62
interimpulso

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

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

8
Jonathan Day

Il est possible de définir un prix spécifique au client d'un article de devis. Par conséquent, quelque chose comme ça 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...

7
Simon

Si je dois partager ma solution que j'ai faite sur la base de Simon, j'ai réussi à réécrire la fonction de sauvegarde de classe de modèle de devis.

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
Deepak Bhatta

La réponse de Jonathan est probablement la meilleure pour la plupart des situations. Mais certains clients pourraient ne pas aimer la façon dont les remises sur le panier sont affichées dans le panier. J'ai récemment réalisé un projet (avec Magento 1.3.3) où le client n'aimait pas comment chaque élément de campagne affichait toujours le prix complet ainsi que le sous-total, avec une ligne de remise en dessous du sous-total - il voulait voir le prix de chaque article réduit et le sous-total indique également le prix réduit. Il vraiment n'aimait pas avoir la ligne Discount après la ligne Subtotal.

Quoi qu'il en soit, si vous vous trouvez dans le même bateau, une approche consiste à remplacer les méthodes getCalculationPrice () et getBaseCalculationPrice () dans Mage_Sales_Model_Quote_Address_Item et Mage_Sales_Model_Quote_Item. Je sais que ce n'est pas toujours joli à remplacer, bien mieux d'utiliser des événements, mais dans ce cas, je ne pouvais pas faire fonctionner les événements de manière transparente à la fois sur le frontend et le backend. Je ne sais pas si cette approche fonctionnera dans Magento 1.4+.

4
shaune

J'ai eu le même problème et je ne suis pas développeur. Ce que j'ai fait a été ajouté un nouvel attribut de prix dans le backend de magento appelé "prix du site". Sur la page du produit, cela montrait le prix plus élevé de 100 $. le prix réel de l'article était de 90 $. Ainsi, lorsque le client l'ajoute au panier, il voit le prix réel de l'article, mais sur la page du produit, il voit le prix de l'attribut personnalisé de 100 $

si tous vos prix sur la page du produit sont un% plus élevé que le prix réel, multipliez simplement le prix de votre produit par le 1 + pour cent. Donc, si vous voulez ajouter 10% à tous vos prix, faites le prix * 1.1 Cela affichera votre prix comme 10% plus élevé, mais lorsque le client ajoutera au panier, il verra le prix réel.

3
knowzero