Programowo dodaj produkt do koszyka ze zmianą ceny

Chcę programowo dodać produkt do koszyka. Chcę również zmienić cenę produktu po dodaniu do koszyka.

Załóżmy, że cena mojego produktu wynosi $100. Chciałem go zmienić na $90 po dodaniu do koszyka.

Dodałem produkt do koszyka. Nie jestem jednak w stanie zmienić ceny produktu.

Czy to możliwe?

Oto kod do dodania produktu do koszyka: -

$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

Po zagłębieniu się w główny kod Magento, odkryłem, że musisz użyć $item->getProduct()->setIsSuperMode(true), Aby $item->setCustomPrice() i $item->setOriginalPrice() działały.

Oto przykładowy kod, którego możesz użyć w obserwatorze, który nasłuchuje zdarzeń checkout_cart_product_add_after lub checkout_cart_update_items_after. Kod jest logicznie taki sam, z wyjątkiem checkout_cart_product_add_after jest wywoływany dla tylko jednego elementu i checkout_cart_update_items_after jest wywoływany dla wszystkich elementów w Koszyku. Ten kod jest rozdzielany/duplikowany na 2 metody tylko jako przykład.

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

Event: 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-29 21:28:58

Magento zmieniło sposób obliczania cen w Koszyku, co sprawia, że bardzo trudno jest to zrobić w wersji 1.4. Jeśli ustawisz cenę za pomocą obserwatora lub innego urządzenia, prawie na pewno zostanie ona nadpisana z powrotem do ceny katalogowej.

Efektywnie, musisz użyć reguł koszyka zakupów, aby to zaimplementować.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 12:46:37

Możliwe jest ustawienie ceny dla konkretnego klienta przedmiotu wyceny. Stąd coś takiego powinno to zrobić:

$quoteItem = $quote->addProduct($product, $qty);
$quoteItem->setCustomPrice($price);
// we need this since Magento 1.4
$quoteItem->setOriginalCustomPrice($price);
$quote->save();
Mam nadzieję, że to pomoże...
 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-11 19:57:16

Odpowiedź Jonathana jest prawdopodobnie najlepsza w większości sytuacji. Ale niektórym klientom może się nie spodobać, jak rabaty na koszyk są wyświetlane w Koszyku. Niedawno zrobiłem projekt (z Magento 1.3.3), w którym Klientowi nie podobało się, jak każda pozycja linii nadal pokazywała pełną cenę, a także subtotal, z linią rabatową poniżej subtotal-chciał zobaczyć cenę każdego przedmiotu zdyskontowanego, a subtotal pokazuje również zdyskontowaną cenę. On [1]} Naprawdę [2]} nie lubił mieć Linia rabatowa po linii Subtotal.

W każdym razie, jeśli znajdziesz się w tej samej łodzi, jednym z sposobów jest nadpisanie metod getCalculationPrice() i getBaseCalculationPrice() w Mage_Sales_Model_Quote_Address_Item i Mage_Sales_Model_Quote_Item. Wiem, że nie zawsze jest ładnie nadpisać, dużo lepiej używać zdarzeń, ale w tym przypadku nie mogłem sprawić, aby zdarzenia działały płynnie zarówno na frontendzie, jak i backendzie. Nie wiem, czy to podejście będzie działać w 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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-25 15:34:04

Jeśli muszę podzielić się moim rozwiązaniem, które zrobiłem na bazie Simona, to udało mi się przepisać funkcję zapisu klasy modelu cytatu.

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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 09:26:32

Miałem ten sam problem i nie jestem deweloperem. To, co zrobiłem, dodano nowy atrybut ceny w backendzie magento o nazwie "Cena witryny". Na stronie produktu pokazało to wyższą cenę $100. rzeczywista cena przedmiotu wynosiła 90 dolarów. kiedy kupujący doda go do koszyka, zobaczy rzeczywistą cenę produktu, ale na stronie produktu zobaczy niestandardową cenę atrybutu $100

Jeśli wszystkie ceny na stronie produktu są ustawione % wyższe, to prawdziwa cena po prostu pomnożyć swój produkt cena 1 + procent. Więc jeśli chcesz dodać 10% do wszystkich swoich cen do ceny*1.1 Spowoduje to wyświetlenie ceny o 10% wyższej, ale gdy kupujący doda do koszyka, zobaczy rzeczywistą cenę.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-22 19:29:53