장바구니에 Magento Multiple 쿠폰 적용


9

카트에 여러 쿠폰을 적용하기 위해 2 일 동안 일해 왔으며 사용할 수있는 모듈이 있음을 알고 있습니다. 그러나 나는 그것을 사용하고 싶지 않습니다. 단일 주문에서 둘 이상의 쿠폰 코드를 적용 할 수 있도록 일부 사용자 정의 코드를 원합니다.

도와주세요. 나는 같은 일을 한 후에 매우 피곤합니다. 여기에 이미지 설명을 입력하십시오



Btw, 귀하의 질문은 2013 년부터 위에 링크 한 것과 매우 유사합니다.
Tim Hallman

@Tim ~ ​​Magento의 기존 방법을 무시하고 판매 테이블에 직접 열을 추가해야하기 때문에 이것이 최선의 방법이라고 생각하지 않습니다. 나는 실제로 이것을 가지고 놀았으며 2 번의 재 작성과 몇 줄의 코드로 쉽게 달성 할 수 있습니다. 또한 해당 링크의 답변은 2 개의 코드 만 추가 할 수 있습니다. 약간의 답변을 게시합니다
Shaughn

@Shaughn pls는 코드를 게시합니다.
Zaheerabbas

나에게 zip 예제를 주거나 좀 더 구체적인 디렉토리를 부탁드립니다.
alexmalara

답변:


14

사용자 정의 모듈에서 다음을 추가하십시오 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>

첫 번째의 재 작성 Mage_SalesRule_Model_Quote_DiscountNamespace_Module_Rewrite_SalesRule_Model_Quote_Discount

두 번째는 오버로드 된 컨트롤러입니다 Mage_Checkout_CartController

다음 파일을 추가하고 app/code/community/Namespace/Module/controllers/Checkout/CartController.php 다음 코드를 삽입하십시오.

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

쿠폰 코드를 ","으로 구분하는 섹션을 추가 한 것을 알 수 있습니다. 이것은 분명히 더 세련 될 수 있으며 추가 검사 등을 추가하고 싶을 수도 있지만이 코드는 박쥐에서 바로 작동해야합니다.

그리고 마지막으로 모든 마술을하는 조각을 추가해야합니다. 파일 추가app/code/community/Namespace/Module/Rewrite/SalesRule/Model/Quote/Discount.php

내용을 추가하십시오 :

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

기본적으로 이것이하는 일은 쿠폰을 끊고 각 쿠폰 코드를 반복하며 견적 총계를 계산하고 업데이트하는 것입니다.

테스트하기 위해 2 개의 쇼핑 바구니 규칙을 설정했습니다.

  • 테스트 1-10 % 제품 가격 할인-추가 규칙 처리 중지 : 아니오
  • 테스트 2-10 % 제품 가격 할인-추가 규칙 처리 중지 : 아니오

쿠폰 없음 : 쿠폰 없음

쿠폰 테스트 1 추가 : 추가 쿠폰 테스트 1

쿠폰 테스트 2 추가 추가 쿠폰 테스트 1

고정 금액 할인으로 테스트했으며 예상대로 작동합니다.

그리고 내가 말했듯이, 중복 검사를 위해 추가 검사를 추가해야 할 수도 있지만 여기서 시작할 수 있습니다. 프론트 엔드의 경우 코드를 나누는 로직을 추가 할 수 있지만 원하는대로 그대로 또는 그대로 둘 수 있습니다.


또한 네임 스페이스 / 모듈을 실제 모듈 이름 등으로 바꿔야한다는 것을 언급하지
않았습니다

이 답변을 편집 한 후에는 위의 스크린 샷과 같이 작동합니다. 여러 쿠폰을 적용한 후 특정 쿠폰을 취소하는 방법은 무엇입니까?
Zaheerabbas

감사합니다 Shaughn 당신이 대답, 그것은 magento 1.9에서 나를 위해 일했지만 1.8 버전에서 작동하도록 할 수 없었습니다. 브라우저에는 아무것도 표시하지 않으며 아파치 error.log (magento error / system.log 아님)에 메모리 크기 소진 오류를 던졌습니다. )
Haris

이봐 사담, 메모리 문제는 아마도 많은 문제 중 하나 일 수 있지만 시도 할 수있는 일은 try catch 블록으로 코드를 감싸고 자르는 오류를 기록하는 것입니다. 또한 PHP의 최대 메모리 설정을 확인하고 충분한 메모리가 있는지 확인하십시오 유효한. 루프 직전에 쿠폰 코드를 계산하고 메모리에로드 된 것이 몇 개 있다고 생각되면 얼마나 있는지 확인할 수 있습니다.
Shaughn

1
동일한 쿠폰 코드가 여러 번 사용되는 것을 쉽게 방지하려면 array_unique $ couponArray = array_unique (explode ( ',', $ couponCode));
Julian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.