Le coupon Magento Multiple s'applique sur le panier

9

Je travaille depuis 2 jours pour appliquer plusieurs coupons sur le panier, je sais qu'il existe des modules disponibles pour cela. Mais je ne veux pas l'utiliser. Je veux un code personnalisé pour pouvoir appliquer plus d'un code de coupon dans la même commande.

Veuillez aider. je suis très fatigué après avoir travaillé sur les mêmes choses. entrez la description de l'image ici

Zaheerabbas
la source
1
Ici, vous allez stackoverflow.com/questions/15138237/…
Tim Hallman
Btw, votre question est étrangement similaire à celle que je viens de relier ci-dessus, qui date de 2013.
Tim Hallman
@Tim ~ ​​Je ne pense pas que ce soit la meilleure méthode, car cela implique d'ajouter des colonnes directement aux tables de vente en contournant les méthodes conventionnelles de Magento. En fait, j'ai joué avec cela maintenant, et avec 2 réécritures et quelques lignes de code, cela peut facilement être réalisé. De plus, la réponse dans ce lien ne permet d'ajouter que 2 codes.
Je posterai
@Shaughn pls publiez votre code.
Zaheerabbas
pourrait me donner un exemple de zip, ou être des répertoires plus spécifiques, merci
alexmalara

Réponses:

14

Dans votre module personnalisé, ajoutez ce qui suit à config.xml:

<models>
    <salesrule>
        <rewrite>
            <quote_discount>Namespace_Module_Rewrite_SalesRule_Model_Quote_Discount</quote_discount>
        </rewrite>
    </salesrule>
</models>
<frontend>
    <routers>
        <checkout>
            <args>
                <modules>
                    <Namespace_Module before="Mage_Checkout">Namespace_Module_Checkout</Namespace_Module>
                </modules>
            </args>
        </checkout>
    </routers>
</frontend>

La première est une réécriture Mage_SalesRule_Model_Quote_DiscountdeNamespace_Module_Rewrite_SalesRule_Model_Quote_Discount

Le second est le contrôleur surchargé Mage_Checkout_CartController

Ajoutez ensuite le fichier suivant app/code/community/Namespace/Module/controllers/Checkout/CartController.php et insérez le code suivant:

<?php

require_once 'Mage/Checkout/controllers/CartController.php';

class Namespace_Module_Checkout_CartController extends Mage_Checkout_CartController
{
    /**
     * Initialize coupon
     */
    public function couponPostAction()
    {
        /**
         * No reason continue with empty shopping cart
         */
        if (!$this->_getCart()->getQuote()->getItemsCount()) {
            $this->_goBack();
            return;
        }

        $couponCode = (string) $this->getRequest()->getParam('coupon_code');
        if ($this->getRequest()->getParam('remove') == 1) {
            $couponCode = '';
        }
        $oldCouponCode = $this->_getQuote()->getCouponCode();

        if (!strlen($couponCode) && !strlen($oldCouponCode)) {
            $this->_goBack();
            return;
        }

        try {
            $codeLength = strlen($couponCode);
            $isCodeLengthValid = $codeLength && $codeLength <= Mage_Checkout_Helper_Cart::COUPON_CODE_MAX_LENGTH;

            // Combine multiple coupons
            $couponFlag = true;

            if ($isCodeLengthValid) {
                $del = ',';

                if ($oldCouponCode) {

                    if ($oldCouponCode == $couponCode) {
                        $couponCode = $oldCouponCode;
                    } else {
                        $couponCode = $oldCouponCode . $del . $couponCode;
                    }
                }
            } else {
                $couponCode = '';
            }

            $this->_getQuote()->getShippingAddress()->setCollectShippingRates(true);
            $this->_getQuote()->setCouponCode($couponCode)
                ->collectTotals()
                ->save();

            if ($codeLength) {
                if ($isCodeLengthValid && $couponFlag) {
                    $this->_getSession()->addSuccess(
                        $this->__('Coupon code "%s" was applied.', Mage::helper('core')->escapeHtml($couponCode))
                    );
                } else {
                    $this->_getSession()->addError(
                        $this->__('Coupon code "%s" is not valid.', Mage::helper('core')->escapeHtml($couponCode))
                    );
                }
            } else {
                $this->_getSession()->addSuccess($this->__('Coupon code was canceled.'));
            }

        } catch (Mage_Core_Exception $e) {
            $this->_getSession()->addError($e->getMessage());
        } catch (Exception $e) {
            $this->_getSession()->addError($this->__('Cannot apply the coupon code.'));
            Mage::logException($e);
        }

        $this->_goBack();
    }
}

Vous remarquerez que j'ai ajouté une section pour combiner les codes promo délimités par ",". Cela peut évidemment être plus raffiné et vous voudrez peut-être ajouter des vérifications supplémentaires, etc., mais ce code devrait fonctionner immédiatement.

Et enfin, nous devons ajouter la pièce qui fait toute la magie. Ajoutez le fichierapp/code/community/Namespace/Module/Rewrite/SalesRule/Model/Quote/Discount.php

et ajoutez le contenu:

<?php

class Namespace_Module_Rewrite_SalesRule_Model_Quote_Discount extends Mage_SalesRule_Model_Quote_Discount
{
    /**
     * Collect address discount amount
     *
     * @param   Mage_Sales_Model_Quote_Address $address
     * @return  Mage_SalesRule_Model_Quote_Discount
     */
    public function collect(Mage_Sales_Model_Quote_Address $address)
    {
        Mage_Sales_Model_Quote_Address_Total_Abstract::collect($address);
        $quote = $address->getQuote();
        $store = Mage::app()->getStore($quote->getStoreId());
        $this->_calculator->reset($address);

        $items = $this->_getAddressItems($address);
        if (!count($items)) {
            return $this;
        }

        $couponCode = $quote->getCouponCode();
        $couponArray = explode(',',$couponCode);

        foreach ($couponArray as $couponCode) {
            $this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $couponCode);
            $this->_calculator->initTotals($items, $address);

            $eventArgs = array(
                'website_id'        => $store->getWebsiteId(),
                'customer_group_id' => $quote->getCustomerGroupId(),
                'coupon_code'       => $couponCode,
            );

            $address->setDiscountDescription(array());
            $items = $this->_calculator->sortItemsByPriority($items);
            foreach ($items as $item) {
                if ($item->getNoDiscount()) {
                    $item->setDiscountAmount(0);
                    $item->setBaseDiscountAmount(0);
                }
                else {
                    /**
                     * Child item discount we calculate for parent
                     */
                    if ($item->getParentItemId()) {
                        continue;
                    }

                    $eventArgs['item'] = $item;
                    Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);

                    if ($item->getHasChildren() && $item->isChildrenCalculated()) {
                        foreach ($item->getChildren() as $child) {
                            $this->_calculator->process($child);
                            $eventArgs['item'] = $child;
                            Mage::dispatchEvent('sales_quote_address_discount_item', $eventArgs);

                            $this->_aggregateItemDiscount($child);
                        }
                    } else {
                        $this->_calculator->process($item);
                        $this->_aggregateItemDiscount($item);
                    }
                }
            }

            /**
             * process weee amount
             */
            if (Mage::helper('weee')->isEnabled() && Mage::helper('weee')->isDiscounted($store)) {
                $this->_calculator->processWeeeAmount($address, $items);
            }

            /**
             * Process shipping amount discount
             */
            $address->setShippingDiscountAmount(0);
            $address->setBaseShippingDiscountAmount(0);
            if ($address->getShippingAmount()) {
                $this->_calculator->processShippingAmount($address);
                $this->_addAmount(-$address->getShippingDiscountAmount());
                $this->_addBaseAmount(-$address->getBaseShippingDiscountAmount());
            }

            $this->_calculator->prepareDescription($address);
        }

        return $this;
    }
}

Fondamentalement, cela brise la piqûre du coupon, parcourt chaque code de coupon, calcule et met à jour les totaux des devis.

Pour tester, j'ai configuré 2 règles de panier:

  • test 1 - 10% de remise sur le prix du produit - Arrêter le traitement des règles supplémentaires: Non
  • test 2 - 10% de remise sur le prix du produit - Arrêter le traitement des règles supplémentaires: Non

Pas de coupon: pas de coupon

Test de coupon 1 ajouté: test de coupon ajouté 1

Ajout du test de coupon 2 test de coupon ajouté 1

J'ai testé avec une remise à montant fixe et cela fonctionne comme prévu.

Et comme je l'ai dit, vous devrez peut-être ajouter des vérifications supplémentaires, éventuellement pour les doublons, mais c'est par là que vous commenceriez. Pour le frontend, vous pouvez ajouter une logique divisant les codes comme vous préférez ou les laisser tels quels.

Shaughn
la source
Vous avez également oublié de mentionner, vous devrez évidemment remplacer Namespace / Module par le nom de votre module, etc.
Shaughn
après avoir édité cette réponse maintenant, cela fonctionne comme ci-dessus screenshot.now comment puis-je annuler un coupon spécifique après avoir appliqué plusieurs coupons.
Zaheerabbas
Merci Shaughn pour votre réponse, cela a fonctionné pour moi sur magento 1.9 mais je n'ai pas pu le faire fonctionner sur la version 1.8, il n'affiche rien dans le navigateur et jette une erreur de taille de mémoire épuisée dans apache error.log (pas magento error / system.log )
Haris
Hey Saddam, le problème de mémoire est probablement l'un des nombreux problèmes, mais ce que vous pouvez faire est d'envelopper le code dans un bloc try catch et de consigner toutes les erreurs qui surviennent.Vérifiez également le paramètre de mémoire maximale en php et assurez-vous d'avoir suffisamment de mémoire disponible. Juste avant la boucle, vous pouvez compter les codes promo et vérifier combien il y en a car je soupçonne qu'il y en a quelques-uns qui sont chargés en mémoire.
Shaughn
1
Pour empêcher facilement l'utilisation multiple des mêmes codes de réduction, vous pouvez simplement utiliser array_unique $ couponArray = array_unique (explode (',', $ couponCode));
Julian