1

在这里和谷歌中一直在寻找类似的问题,我很惊讶我找不到任何类似的东西。

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

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

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

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

我们目前正在使用 OSCommerce 并很快过渡到 Magento。现在我们正在做的模拟这种行为是在我们的常规网站上的商店访问页面上有一个文本字段,用户可以在其中单击一个区域或输入优惠券代码。如果他们输入代码,他们将被重定向到具有特价的定制商店。

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

我还没有看到任何这样做的扩展。有没有人知道这样的事情是否可以完成,如果可以,怎么做?

4

2 回答 2

2

我很好奇乔纳森你是怎么做到的,我没有采用你的方法,我的方法有点复杂。我的确实允许有人在 url 中发布优惠券代码,但我设置了一个 cookie 和所有这些。我基本上在标题中设置了我自己的表单,用户可以输入优惠券代码并应用它,并将优惠券放在电子邮件活动的 url 中。

我需要一段时间才能详细回顾它,所以我将发布一些代码片段,也许可以帮助您继续前进,并尝试 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

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;
}
于 2011-02-01T02:33:47.393 回答
1

这绝对可以实现。它涉及编写一个自定义模块(从此处开始) ,其中包含一个控制器,该控制器接受您的优惠券字段的值,为该用户启动结帐会话($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 和其他非简单产品类型,价格对象是不同的。

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

于 2011-02-01T00:34:50.413 回答