简体   繁体   中英

Magento change shipping rate in one page checkout for COD

My question is quite simple. I need to change the shipping rate cost in one page checkout to "0" once the user select COD as payment method in one page checkout. I think I can do this easely with an observer. Could you please helpme to know what event should I observe?.

Can I use checkout_controller_onepage_save_shipping_method ?. Any kind of help will be highly appreciated!!

Details Posted By OP as answer

I override the Mage_Checkout_Model_Type_Onepage class and modify the savePayment method. Then I did this:

1.- A first try:

public function savePayment($data)
{
.....
....
$payment = $quote->getPayment();
$payment->importData($data);
$quote->save();

//My custom code
if($data['method']=='cashondelivery'){
        $shipping = $quote->getShippingAddress();
        $address = $quote->getBillingAddress();
        $shipping->addData($address)->setShippingMethod('flatrate_flatrate');
    }

Where my flatrate_flatrate is 0. Unfortunately it doesn't work well. This snippet set to 0 my Grant Total.

My second try was:

public function savePayment($data)
{
.....
....
$payment = $quote->getPayment();
$payment->importData($data);
$quote->save();

//My custom code
if($data['method']=='cashondelivery'){
        $this->getQuote()->getShippingAddress()->setShippingAmount(0);
        $this->getQuote()->getShippingAddress()->setBaseShippingAmount(0);
    }

This code works but only a few times, I don't understand why ??.. Could somebody helpme to fix this please?. Any kind of help will be highly appreciated.

Kind regards!


Ok. Now I have this and it works but it doesn't update the grand total amount. Even the order is processed with the normal shipping cost. I mean, finally it doesn't update anything. Could somebody in someway give me a hand on this please?.

     if($data['method']=='cashondelivery'){
        $quote->getShippingAddress()->setShippingMethod('flatrate_flatrate');
        $quote->getShippingAddress()->setShippingAmount(0);
        $quote->getShippingAddress()->setBaseShippingAmount(0);
        $quote->getShippingAddress()->setShippingInclTax(0);
        $quote->getShippingAddress()->setBaseShippingInclTax(0);
        $quote->collectTotals(); 
        $quote->save();
    }

Warming regards!


Ok, I did something crazy but it seems it works (at least partially). I override Mage_Checkout_OnepageController too and add it a new method call actualizaShippingMethodAction.

It looks like this:

public function actualizaShippingMethodAction()
{
    if ($this->_expireAjax()) {
        return;
    }
    if ($this->getRequest()->isPost()) {
        $data = $this->getRequest()->getPost('shipping_method', '');
        $result = $this->getOnepage()->saveShippingMethod($data);
        // $result will contain error data if shipping method is empty
        if (!$result) {
            $this->getOnepage()->getQuote()->collectTotals();
        }
        $this->getOnepage()->getQuote()->collectTotals()->save();
    }
}

Now in my original class that is overriding (Mage_Checkout_Model_Type_Onepage) I did this.

if($data['method']=='cashondelivery'){
        $cliente = new Varien_Http_Client();
        $_configuracion = array('maxredirects'=>5, 'timeout'=>30);
        $llamada = Mage::getBaseUrl()."checkout/onepage/actualizaShippingMethod/";
        $cliente->setUri($llamada)
        ->setConfig($_configuracion)
        ->setMethod(Zend_Http_Client::POST)
        ->setParameterPost('shipping_method','flatrate_flatrate');

        $respuesta = $cliente->request();
        $quote->getShippingAddress()->setShippingAmount(0);
        $quote->getShippingAddress()->setBaseShippingAmount(0);
        $quote->getShippingAddress()->setShippingInclTax(0);
        $quote->getShippingAddress()->setBaseShippingInclTax(0);
        $quote->collectTotals()->save();
    }

    $this->getCheckout()
        ->setStepData('payment', 'complete', true)
        ->setStepData('review', 'allow', true);

    return array();

Now the order is passing without shipping cost as spected but the order review (summary) is not updating the final costs. And I thinks this solution has a bug because if the user returns and select another payment method the shipping cost is 0 again.

Any kind of help, whatever, will be highly, highly appreciated

THANKS

Finally I have a solution and I think is an answer to the original question. If not please pardon me.

Forget to override savePayment($data) on Mage_Checkout_Model_Type_Onepage. Just focus on overriding Mage_Checkout_OnepageController, and add to the savePaymentAction() method the following code.

            $data = $this->getRequest()->getPost('payment', array());

        /*Custom code*/
        if($data['method']=='cashondelivery'){//Only if payment method is cashondelivery
            $result = $this->getOnepage()->savePayment($data);
            // get section and redirect data
            $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
            if (empty($result['error']) && !$redirectUrl) {
                $this->loadLayout('checkout_onepage_review');
                $result['goto_section'] = 'review';
                $result['update_section'] = array(
                    'name' => 'review',
                    'html' => $this->_getReviewHtml()
                );
            }
            if ($redirectUrl) {
                $result['redirect'] = $redirectUrl;
            }

            //Update totals for Shipping Methods
            $resultado = $this->getOnepage()->saveShippingMethod('flatrate_flatrate');
            $this->getOnepage()->getQuote()->collectTotals()->save();


        }else{

            $result = $this->getOnepage()->savePayment($data);
            // get section and redirect data
            $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
            if (empty($result['error']) && !$redirectUrl) {
                $this->loadLayout('checkout_onepage_review');
                $result['goto_section'] = 'review';
                $result['update_section'] = array(
                    'name' => 'review',
                    'html' => $this->_getReviewHtml()
                );
            }
            if ($redirectUrl) {
                $result['redirect'] = $redirectUrl;
            }

            //Return the original values according with the initial user sellection
            //I use a session variable to store the original selection
            $shippingMethod = Mage::getSingleton('core/session')->getShippingInicial();
            $resultado = $this->getOnepage()->saveShippingMethod($shippingMethod);
            $this->getOnepage()->getQuote()->collectTotals()->save();

        }


    } catch (Mage_Payment_Exception $e) {
        if ($e->getFields()) {
  ...

Then you have to override saveShippingMethodAction() and add the following code.

...

 $result = $this->getOnepage()->saveShippingMethod($data);

        //We store the Shipping Method initial selection

        Mage::getSingleton('core/session')->setShippingInicial($data);

        // $result will contain error data if shipping method is empty
        if (!$result) { ...

If you test this you will find that it works as expected. But now it takes 2 loading times to correctly show the total costs in the review part. I read this question ( IWD one page checkout extension Magento: review refresh ) but it doesn't help a lot.

Could somebody point me in the right direction to update the review part twice?.

WARMING REGARDS!

Could somebody have an idea how to achieve this?. Regards!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM