Se aplican cupones Magento Multiple en el carrito

9

He estado trabajando durante 2 días para aplicar cupones múltiples en el carrito. Sé que hay módulos disponibles para eso. Pero no quiero usarlo. Quiero un código personalizado para poder aplicar más de 1 código de cupón en un solo pedido.

Por favor ayuda. Estoy muy cansado después de trabajar en lo mismo. ingrese la descripción de la imagen aquí

Zaheerabbas
fuente
1
Aquí tienes stackoverflow.com/questions/15138237/…
Tim Hallman
Por cierto, su pregunta es inquietantemente similar a la que acabo de vincular arriba, que es de 2013.
Tim Hallman
@Tim ~ ​​No creo que sea el mejor método, ya que implica agregar columnas directamente a las tablas de ventas sin pasar por los métodos convencionales de Magento. De hecho, jugué con esto ahora, y con 2 reescrituras y algunas líneas de código, esto se puede lograr fácilmente. Además, la respuesta en ese enlace solo permite agregar 2 códigos. Publicaré una respuesta en un momento
Shaughn
@Shaughn por favor publique su código.
Zaheerabbas
podría darme un ejemplo zip, o ser directorios más específicos, por favor, gracias
alexmalara

Respuestas:

14

En su módulo personalizado, agregue lo siguiente a 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>

El primero es una reescritura de Mage_SalesRule_Model_Quote_DiscounttoNamespace_Module_Rewrite_SalesRule_Model_Quote_Discount

El segundo es el controlador sobrecargado. Mage_Checkout_CartController

A continuación, agregue el siguiente archivo app/code/community/Namespace/Module/controllers/Checkout/CartController.php e inserte el siguiente código:

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

Notarás que agregué una sección para combinar códigos de cupón delimitados por ",". Obviamente, esto puede ser más refinado y es posible que desee agregar una comprobación adicional, etc., pero este código debería funcionar directamente.

Y finalmente necesitamos agregar la pieza que hace toda la magia. Agrega el archivoapp/code/community/Namespace/Module/Rewrite/SalesRule/Model/Quote/Discount.php

y agrega el contenido:

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

Básicamente, lo que hace es romper la picadura del cupón, recorrer cada código de cupón, calcular y actualizar los totales de las cotizaciones.

Para probar, he configurado 2 reglas de carrito de compras:

  • prueba 1 - 10% de descuento en el precio del producto - Detener el procesamiento de reglas adicionales: No
  • prueba 2 - 10% de descuento en el precio del producto - Detener el procesamiento de reglas adicionales: No

Sin cupón: sin cupón

Prueba de cupón agregada 1: prueba de cupón añadido 1

Prueba de cupón agregada 2 prueba de cupón añadido 1

He probado con un descuento de cantidad fija y esto funciona como se esperaba también.

Y como dije, es posible que deba agregar una verificación adicional, posiblemente para duplicados, pero aquí es donde comenzaría. Para el frontend, puede agregar algo de lógica para dividir los códigos como prefiera o dejarlos como están.

Shaughn
fuente
También olvidó mencionar, usted obviamente tendrá que reemplazar Espacio de nombres / módulo con el nombre del módulo actual, etc.
Shaughn
después de editar esta respuesta ahora funciona como la captura de pantalla anterior. ahora, ¿cómo puedo cancelar un cupón específico después de aplicar varios cupones?
Zaheerabbas
Gracias Shaughn por su respuesta, funcionó para mí en magento 1.9 pero no pude hacerlo funcionar en la versión 1.8, no muestra nada en el navegador y arroja el error de tamaño de memoria agotada en apache error.log (no magento error / system.log )
Haris
Hola Saddam, el problema de la memoria es probablemente uno de los muchos problemas, pero lo que podrías hacer es envolver el código en un bloque de prueba y registrar cualquier error que surja. También verifica la configuración de memoria máxima en php y asegúrate de tener suficiente memoria disponible. Justo antes del bucle, podría contar los códigos de cupón y verificar cuántos hay, ya que sospecho que hay algunos que están cargados en la memoria.
Shaughn 01 de
1
Para evitar fácilmente el uso múltiple de los mismos códigos de cupón, puede usar array_unique $ couponArray = array_unique (explotar (',', $ couponCode));
Julian