Wie kann ich nur ein Produkt in einem Warenkorb zulassen?


18

Wir haben eine Anforderung, wonach ein Kunde jeweils nur ein Produkt in den Warenkorb legen darf. Er kann jedoch eine beliebige Menge dieses Produkts hinzufügen.

Wie kann ich verhindern, dass ein Produkt in den Warenkorb gelegt wird, wenn sich bereits ein Produkt im Warenkorb befindet?

Kann jemand dabei helfen?


1
Ich denke, das ist was Sie brauchen: crearegroup-ecommerce.co.uk/blog/magento-tips/… Die andere Option ist, die Aktion zum Hinzufügen eines Produkts neu zu schreiben und ein benutzerdefiniertes Ereignis auszulösencheckout_cart_product_add_before , z. B. markshust.com/2012/
08/27

@enenen: das ist cool, aber wie kann ich verhindern, dass das Produkt in diesem Beobachter in den Einkaufswagen gelegt wird?
Shathish

Antworten:


20

Die Ereignisse catalog_product_type_prepare_full_optionsund catalog_product_type_prepare_lite_optionssind deine Freunde

<?xml version="1.0"?>
<config>
    <modules>
        <Fooman_Example>
            <version>0.1.0</version>
        </Fooman_Example>
    </modules>
    <global>
        <models>
            <fooman_example>
                <class>Fooman_Example_Model</class>
            </fooman_example>
        </models>
        <helpers>
            <fooman_example>
                <class>Fooman_Example_Helper</class>
            </fooman_example>
        </helpers>
    </global>
    <frontend>
        <events>
            <catalog_product_type_prepare_full_options>
                <observers>
                    <fooman_example_catalog_product_type_prepare>
                        <class>Fooman_Example_Model_Observer</class>
                        <method>catalogProductTypePrepare</method>
                    </fooman_example_catalog_product_type_prepare>
                </observers>
            </catalog_product_type_prepare_full_options>
        </events>
    </frontend>
</config>

Dann in deiner Observer Klasse

<?php

class Fooman_Example_Model_Observer
{
    public function catalogProductTypePrepare($observer)
    {
        $quote = Mage::getSingleton('checkout/session')->getQuote();
        if($quote->getItemsCount()>=1){
            Mage::throwException('You can only buy one product at a time.');
        }
    }
}

catalog_product_type_prepare_lite_optionsist eine Premiere für mich! schön gemacht.
Philwinkle

4
@philwinkle es ist sehr praktisch für alles, bevor es in den Warenkorb gelegt wird. Ich denke, es wird von vielen Cheatsheets übersehen, weil ein normales Grep nur Mage :: dispatchEvent erzeugt ($ eventName, ohne die vorangegangene Zeile $ eventName = sprintf ('catalog_product_type_prepare_% s_options', $ processMode);
Kristof at Fooman

Nun, das hat wie ein Zauber funktioniert.
Deepanshu Goyal

Fooman, ich bin es
Amit Bera

8

Anstatt einen Controller neu zu schreiben (bitte nicht), schreiben Sie die addProductMethode neu, um das Limit zu berücksichtigen:

class YourCompany_YourModule_Model_Cart extends Mage_Checkout_Model_Cart
{
    public function addProduct($productInfo, $requestInfo=null){
        if($this->getItemsCount()>1){
            Mage::throwException(Mage::helper('checkout')->__('Cannot add item - cart quantity would exceed checkout the limit of %s per person.', 1));
        }
        parent::addProduct($productInfo, $requestInfo);
    }
}

Wenn Sie Lust haben, ersetzen Sie das 1obige durch Mage::getStoreConfig('checkout/options/max_cart_qty)und stellen Sie die config.xml Ihres Moduls wie folgt ein:

<default>
    <checkout>
        <options>
            <max_cart_qty>1</max_cart_qty>
        </options>
    </checkout>
</default>

Dieser Wert wird nun über den XML-Wert gesteuert. Wenn Sie wirklich, wirklich Lust haben möchten , fügen Sie dies der system.xml Ihres neuen Moduls hinzu:

<config>
    <sections>
        <checkout>
            <groups>
                <options>
                    <fields>
                        <max_cart_qty translate="label">
                            <label>Maximum Quantity Allowed in Cart (total qty)</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>100</sort_order>
                            <show_in_default>1</show_in_default>
                        </max_cart_qty>
                    </fields>
                </options>
            </groups>
        </checkout>
    </sections>
</config>

Denken Sie daran, dass Sie ein <depends>Mage_Checkout</depends>für Ihr Modul festlegen müssen, um die vordefinierte Systemkonfiguration zu übernehmen.


Vielen Dank, Ihre Antwort ist "wirklich schick", aber Foomans Antwort stimmte mit dem überein, was ich bereits ausprobiert hatte, also haben Sie das als Antwort akzeptiert. Aber wenn ich nicht angefangen hätte, Beobachter einzusetzen, hätte ich deine Methode angewendet :).
Shathish

1
Na sicher! @fooman war richtig auf - das war auch für mich
lehrreich

2

Eine Möglichkeit besteht darin, die addAction von Mage_Checkout_CartController neu zu schreiben.

Prüfen Sie also, ob sich bereits ein Produkt im Warenkorb befindet und ob ja eine entsprechende Fehlermeldung angezeigt wird. Wenn nicht, können Sie die übergeordnete Methode aufrufen, die den gesamten Add-Prozess ausführt:

    if (count($this->_getCart()->getProductIds()) > 0) {
        $this->_goBack();
    } else {
        parent::addAction();
    }

Es tut mir leid, $this->_goBack();funktioniert nicht! Ich gerate in den if-Zustand, aber das Produkt wird noch hinzugefügt.
Shathish

Was passiert, wenn Sie gerade an diesem Punkt beenden, nur um zu debuggen, was wirklich passiert, da der gesamte addAction-Prozess nicht ausgeführt werden sollte
Tobias,

Wenn

aber fügt es das Produkt hinzu?
Tobias

3
bitte oh bitte nicht umschreiben controller
philwinkle

1

Ich denke, Sie können einen Beobachter verwenden und die folgenden Ereignisse werden nützlich sein, um die Bedingungen zu überprüfen, die Sie wollen. (Möglicherweise sind einige der Ereignisse in der von Ihnen verwendeten Magento-Version nicht enthalten.)

checkout_cart_save_before

checkout_cart_product_add_after

checkout_cart_update_items_before

checkout_cart_update_items_after

checkout_cart_save_after

Ich versuche es bereits mit checkout_cart_product_add_afterevent. Die Frage ist, wie ich verhindern kann, dass das Produkt in den Warenkorb gelegt wird.
Shathish

oder wenn es bereits hinzugefügt wurde, wie kann es entfernt werden?
Shathish

1

Vielleicht eine Idee für das linke Feld, aber wie wäre es mit der Verwendung des catalog_product_is_salable_afterEvents?

Sie können hier überprüfen, ob sich das Produkt im Warenkorb befindet oder ob sich ein anderes Produkt im Warenkorb befindet. Wenn sich ein anderes Produkt in der Warenkorbaktualisierung befindet, wird das Attribut 'is_salable' des 'salable'-Objekts an den Beobachter mit false übergeben.

HINWEIS : Dies wurde nicht getestet und ist nur eine Idee. Es schlägt fehl, wenn Ihre Vorlage$product->isSaleable()vor dem Anzeigen der Schaltflächenicht überprüft wird. Es würde auch nur die Schaltfläche entfernen und den Hinzufügungsprozess nicht stoppen, wenn der Benutzer die URL erraten könnte.


1

Ich weiß, dass dieses Thema etwas altes ist, aber ich hatte ein ähnliches Problem. Ich möchte nur einen Artikel im Warenkorb haben und wenn der Kunde einen neuen hinzufügt, möchte ich den alten durch den neuen ersetzen. Also überschreibe ich die AddAction ( hier wie folgt beschrieben :

public function addAction(){
    $items = $this->_getCart()->getItems();
            foreach ($items as $item)
                    {
                            $itemId = $item->getItemId();
                            $this->_getCart()->removeItem($itemId);
                    }
    parent::addAction();

}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.