Comment autoriser un seul produit dans un panier?

18

Nous avons une exigence, dans laquelle un client ne sera autorisé à ajouter qu'un seul produit au panier à la fois. Cependant, il / elle peut ajouter n'importe quelle quantité de ce produit.

Comment puis-je empêcher un produit de s'ajouter au panier s'il y a déjà un produit dans le panier?

Quelqu'un peut-il m'aider à ce sujet?

Shathish
la source
1
Je pense que c'est ce dont vous avez besoin: crearegroup-ecommerce.co.uk/blog/magento-tips/… L'autre option est de réécrire l'action pour ajouter un produit et d'y déclencher un événement personnalisé checkout_cart_product_add_before , par exemple markshust.com/2012/
27/08
@enenen: c'est cool, mais comment puis-je empêcher le produit d'être ajouté au panier dans cet observateur?
Shathish

Réponses:

20

Les événements catalog_product_type_prepare_full_optionset catalog_product_type_prepare_lite_optionssont vos amis

<?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>

Puis dans votre classe Observer

<?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.');
        }
    }
}
Kristof chez Fooman
la source
catalog_product_type_prepare_lite_optionsest une première pour moi! Bien fait.
philwinkle
4
@philwinkle, il est très pratique pour tout juste avant d'ajouter au panier. Je pense que cela manque de beaucoup de cheatsheets car un grep normal ne produit que Mage :: dispatchEvent ($ eventName, manque la ligne précédente $ eventName = sprintf ('catalog_product_type_prepare_% s_options', $ processMode);
Kristof au Fooman
bien cela a fonctionné comme un charme.
Deepanshu Goyal
Fooman, c'est moi grts
Amit Bera
8

Au lieu de réécrire un contrôleur (s'il vous plaît oh s'il vous plaît ne faites pas cela), réécrivez plutôt la addProductméthode pour tenir compte de la limite:

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

Si vous voulez faire preuve de fantaisie, remplacez ce qui 1précède par Mage::getStoreConfig('checkout/options/max_cart_qty)et définissez le config.xml suivant de votre module:

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

Cette valeur est désormais contrôlée via la valeur XML. Si vous voulez devenir vraiment, vraiment fantaisiste , ajoutez ceci au system.xml de votre nouveau module:

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

N'oubliez pas que vous devez définir un <depends>Mage_Checkout</depends>pour votre module afin de vous greffer sur sa configuration système prédéfinie.

philwinkle
la source
Merci beaucoup, votre réponse est "vraiment fantaisiste", mais la réponse de Fooman était conforme à ce que j'essayais déjà, alors j'ai accepté cela comme réponse. Mais si je n'ai pas commencé à utiliser des observateurs, j'aurais utilisé votre méthode :).
Shathish
1
Bien sûr! @fooman avait raison - c'était instructif pour moi aussi :)
philwinkle
2

Une façon possible consiste à réécrire l'addAction de Mage_Checkout_CartController.

Vérifiez donc s'il y a déjà un produit dans le panier et si oui, affichez un message d'erreur approprié. Sinon, vous pouvez appeler la méthode parent qui effectue le processus d'ajout complet:

    if (count($this->_getCart()->getProductIds()) > 0) {
        $this->_goBack();
    } else {
        parent::addAction();
    }
Tobias
la source
Je suis désolé, $this->_goBack();ça ne marche pas! J'entre dans la condition if mais le produit est toujours ajouté.
Shathish
Que se passe-t-il si vous venez de quitter à ce stade, juste pour déboguer ce qui se passe réellement, parce que le processus addAction entier ne doit pas être exécuté
Tobias
donner la sortie à ce moment-là quitte l'exécution en me donnant un écran vide
Shathish
mais ajoute-t-il le produit?
Tobias
3
s'il vous plaît oh s'il vous plaît ne pas réécrire les contrôleurs
philwinkle
1

Je pense que vous pouvez utiliser un observateur et les événements suivants seront utiles pour vérifier les conditions que vous souhaitez. (Peut-être que certains des événements peuvent ne pas être dans la version de Magento que vous utilisez).

checkout_cart_save_before

checkout_cart_product_add_after

checkout_cart_update_items_before

checkout_cart_update_items_after

checkout_cart_save_after
Sukeshini
la source
J'essaie déjà avec l' checkout_cart_product_add_afterévénement, la question est de savoir comment puis-je empêcher le produit d'être ajouté au panier?
Shathish
ou s'il est déjà ajouté, comment le supprimer?
Shathish
1

Peut-être un peu une idée de champ gauche, mais que diriez-vous d'utiliser l' catalog_product_is_salable_afterévénement?

Ce que vous pouvez faire ici est de vérifier si le produit est dans le panier ou s'il y a un autre produit dans le panier. Quand il y a un autre produit dans la mise à jour du panier, l'attribut 'is_salable' de l'objet 'vendable' est passé à faux à l'observateur.

NOTEZ que cela n'a pas été testé et n'est qu'une idée. Il échouera si votre modèle ne vérifie pas$product->isSaleable()avant d'afficher le bouton. Cela supprimerait également le bouton et n'arrêterait pas réellement le processus d'ajout si l'utilisateur était capable de deviner l'URL.

David Manners
la source
1

Je sais que ce sujet est ancien, mais j'ai eu un problème similaire. Je veux un seul article dans le panier et si le client en ajoute un nouveau, je veux remplacer l'ancien par le nouveau. Je remplace donc l'addAction (décrit ici comme ceci:

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

}

www.abo-killer.de
la source