有没有办法用优惠券代码刷新Magento *目录*(不是购物车)价格?

时间:2011-01-31 23:06:01

标签: magento catalog discounts

在这里和谷歌都在搜索与此类似的问题的高低,我很惊讶我找不到类似的东西。

我熟悉客户群和分层定价,但它不符合我的客户设定的目标。

我们想要的是让用户来我们的Magento商店并以常规价格查看常规主页。此时,我们需要一个突出的文本字段供用户添加优惠券代码,网站将刷新该优惠券代码并显示新的折扣价格,并以正常价格敲出(或通过其他一些视觉方法“削减”。

客户群/分层定价不是解决方案,因为它们要求客户登录。由于所有用户都会看到折扣,因此NOT LOGGED IN组也无济于事。

这在购物车中不可能发生,因为那时为时已晚,这需要在目录级别上进行。

我们目前正在使用OSCommerce并很快转换到Magento。现在我们要模仿这种行为的方法是在Store Access页面上的常规网站上有一个文本字段,用户可以在该页面上点击某个区域或输入优惠券代码。如果他们输入代码,他们会被重定向到具有特殊定价的自定义商店。

我知道通过创建商店视图然后使用相同的功能在Magento中重新创建我们当前的方法很容易,但是当想要移动到更强大的新平台时,这样做似乎很遗憾。

我没有看到任何扩展功能。有没有人能够了解这样的事情是否可以实现,如果是,如何实现?

2 个答案:

答案 0 :(得分:2)

我好奇Jonathon你是怎么做到的,我没有接受你的方法,我的方法有点复杂。我确实允许有人在网址中发布优惠券代码,但我设置了一个cookie以及所有这些。我基本上在标题中设置我自己的表单,用户可以将其添加到优惠券代码中并应用该优惠券以及将优惠券放入电子邮件营销活动的网址中。

我需要一段时间才能详细回顾它,所以我会发布一些代码片段,这些代码片段可能会帮助你开始,尝试Jonathan所说的方式很长。

覆盖购物车控制器并添加您自己的操作。

 public function couponExternalPostAction()
{
        $quote =  $this->_getQuote();
        $couponCode = (string) $this->getRequest()->getParam('coupon_code');
        $validateCoupon = Mage::getModel('package_module/coupon');
        $json = $validateCoupon->addCouponCode($couponCode, $quote, $this->getRequest());

        echo $json;
        return;
}

我还必须覆盖couponPostAction()以正常方式正常工作。

我在自己的模型中有一个addCoupon方法

 public function addCouponCode($code, $quote, $request){
    $couponCode = (string) $code;
    $removed = false;

    if ($request->getParam('remove') == 1) {
        $couponCode = '';
        $removed = true;
    }

    $oldCouponCode = $quote->getCouponCode();

    /* No point in applying the rule again if it is the same coupon code that is in the quote */
    if ($couponCode === $oldCouponCode) {
        $json = $this->_getResponseJson($removed, $couponCode, $quote, false, true);
        return $json;
    }
    // Set the code get the rule base on validation even if it doesn't validate (false), which will also add it to the session,  then get our response
    $quote->setCouponCode(strlen($couponCode) ? $couponCode : '');
    $rule = $this->_validateCoupon($quote,$couponCode);
    // add coupon code to cookie, so we can delete from quote if the user closes their browser and comes back
    if($rule && !$removed){
        Mage::getModel('core/cookie')->set('coupon_code', $couponCode, 0, '/', null, null, null, false);
    }else{
       Mage::getModel('core/cookie')->delete('coupon_code');
    }
    $json = $this->_getResponseJson($removed, $couponCode, $quote, $rule);

    //See if the quote id is set  before saving
    $quoteId = $quote->getQuoteId();

    //Save the quote since everything has been set if not the data wont be set on page refresh
    $quote->save();

    //Set the quote id if it wasn't set before saving the quote. This makes sure we work off the same quote and a new one isn't created.
    if(empty($quoteId)){
        $this->_setQuoteId($quote);
    }

    return $json;
}

验证优惠券

 protected function _validateCoupon($quote,$couponCode){
    $store = Mage::app()->getStore($quote->getStoreId());
    $validator = Mage::getModel('package_module/validator');
    $validator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());

    return $validator->isValidExternalCode($couponCode, $quote->getShippingAddress(),false);
}

我使用自己的验证函数扩展Mage_SalesRule_Model_Validator

 public function isValidExternalCode($couponCode, $address, $setCoupon = true){
    foreach ($this->_getRules() as $rule) {
        if ($rule->getCode() && (in_array(strtolower($couponCode),explode(',',strtolower($rule->getCode()))))) {
            if($setCoupon){
                $address->setCouponCode($couponCode);
            }
            return $rule;
        }
    }
    return false;
}

这里我生成了json响应

rotected function _getResponseJson($removed, $couponCode, $quote, $rule = false, $isDup = false){
    $json = '{"Response":{';
    if($removed){
        $json .= '"success":"Promotional code was cancelled successfully."';
        Mage::getSingleton('checkout/session')->setData('coupon_rule',null);
    }
    if(!$removed && $isDup){
        $json .= '"error":"' . $couponCode . ' is already applied"';
    }else if(!$removed && $rule){
        $json .= '"success":"Promotional code ' . $couponCode . ' has been applied",';
        $json .= '"couponMessage":"<span>' . $rule->getName() . '</span>"';
        Mage::getSingleton('checkout/session')->setData('coupon_rule','<span>' . $rule->getName() .'</span>');
    }else if(!$removed){
        $json .= '"error":"' . $couponCode . ' is not valid"';
        $quote->setCouponCode('');
    }
    $json .= '}}';
    return $json;
}

我还必须覆盖Mage_SalesRule_Model_Quote_Discount

中的collect方法
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());


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

    $this->_calculator->init($store->getWebsiteId(), $quote->getCustomerGroupId(), $quote->getCouponCode());

    $items = $address->getAllItems();
    /* EDITS
     * Moved the if statement for no items in cart down past these previous methods and then if the address type is shipping and the coupon is set
     * add the coupon code to the address to allow the validation to still pick up the coupon code
     */
    if($quote->getCouponCode() && ($address->getAddressType() == Mage_Sales_Model_Quote_Address::TYPE_SHIPPING)){
        $address->setCouponCode($quote->getCouponCode());
    }
    if (!count($items)) {
        return $this;
    }

    $address->setDiscountDescription(array());

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

答案 1 :(得分:1)

这绝对可以实现。它涉及使用控制器编写自定义模块(启动herehere),该控制器接受优惠券字段的值,为该用户启动结帐会话($session = Mage::getSingleton('checkout/session'))并存储优惠券结帐会话中的代码($session->setData('coupon_code',$coupon)。

然后,您可以扩展价格模型以检查会话中的优惠券代码。您可以使用Mage_Catalog_Model_Product_Type_Price语法覆盖自己模块中的<rewrite>。检索优惠券代码($couponCode = Mage::getSingleton("checkout/session")->getData("coupon_code");)。请注意,Bundle和其他非Simple产品类型的Price对象不同。

如果您需要更多信息,我可以发布代码示例。