Search code examples
magentocheckoutrestriction

How to restrict particular products at checkout for particuar location


I want to sell some products for delhi location only, and remaining products will be available for all over india. So how to restrict products at checkout page for other location than delhi ncr, for example, i want sell cakes in delhi only, so if someone proceed to checkout with cake product and customer put other location than delhi ncr so how i restrict that customer to place order.. Please Help


Solution

  • You could use an event observer to accomplish this task. That would allow you to check the customers cart as they try to navigate through the checkout.

    An event that may be helpful to use is checkout_controller_onepage_save_shipping_method. There are many events that you can listen to but this seems to be pretty safe for this question. That event happens after the customer saves their shipping method. Now you know where they want it shipped to. With that knowledge, you can inspect the customers cart, verify that things are OK to continue or halt the progress and redirect them to a custom page. Another option is a CMS page to show the reason they cannot proceed.
    Finally a last option is to just throw an exception at that point and have the error message describe why they are not able to proceed. I would engineer this a bit more complex but to get you learning about event observers I am going to try to keep this as simple as possible. Here are the steps needed to get this accomplished:

    1. Create an attribute on the attribute set for products you are concerned about limiting shipping that we can use when we inspect the cart during checkout. May something like: delhi_only. I would make it a yes/no product attribute and visible on the frontend
    2. Create the event observer in our module. I like to keep things related in the prospective module, so we will create a module called Gallup_Checkout. Create the module declaration in app/etc/modules it should look like this

      <?xml version="1.0" encoding="UTF-8"?>
      <config>
          <modules>
              <Gallup_Checkout>
                  <active>true</active>
                  <codePool>local</codePool>
              </Gallup_Checkout>
          </modules>
      </config>
      
    3. in app/code/local we will create a folder called Gallup

    4. Inside app/code/local/Gallup we will need an etc folder with config.xml inside

      <?xml version="1.0" encoding="UTF-8"?>
      <config>
          <modules>
              <Gallup_Checkout>
              <version>1.0.0</version>
              </Gallup_Checkout>
          </modules>
      <global>
          <events>
              <checkout_controller_onepage_save_shipping_method>
                  <observers>
                      <gallup_checkout>
                          <type>singleton</type>
                          <class>gallup_checkout/observer</class>
                        <method>checkoutControllerOnepageSaveShippingMethod</method>
                      </gallup_checkout>
                  </observers>
              </checkout_controller_onepage_save_shipping_method>
          </events>
          <helpers>
              <gallup_checkout>
                  <class>Gallup_Checkout_Helper</class>
              </gallup_checkout>
          </helpers>
      </global>
      </config>
      
    5. Now Create the blank helper in app/code/local/Gallup/Checkout/Helper/Data.php class Gallup_Checkout_Helper_Data extends Mage_Checkout_Helper_Data{ }

    6. Finally your observer class app/code/local/Gallup/Checkout/Model/Observer.php

          class Gallup_Checkout_Model_Observer{
              /** 
              * @param Varien_Event_Observer $observer
              */
              public function checkoutControllerOnepageSaveShippingMethod( Varien_Event_Observer $observer ){
                  // use a private function so we can do other things in this same event observer if needed in the future
                  $this->_checkoutControllerOnepageSaveShippingMethod( $observer );
              } 
      
      
          private function _checkoutControllerOnepageSaveShippingMethod( $observer ){
              $quote = $observer->getQuote();
      
              foreach ($quote->getAllItems() as $_item){
                  $_dehliAddress      = $this->_checkDehliShippingAddress($quote);
                  $_checkDehliOnly    = $this->_checkDehliOnly($_item->getData('product_id'));
                  /**
                   * Check if this product is dehli only AND the address failed, if so alert the customer
                   */
                  if ( $_checkDehliOnly && !$_dehliAddress){
                      $error_message = 'Sorry, we are unable to continue, you have items in your cart that need to be delivered within Dehli';
                      Mage::getSingleton('core/session')->addError($error_message);
                      Mage::throwException($error_message);
                  }
              }
          }
      
          /**
           * @param $product
           * @return int
            */
          private function _checkDehliOnly($product_id){
              $product = Mage::getModel('catalog/product')->load($product_id);
              // This is saved as a string 0 or 1 so casting it to an int will give us the boolean we are expecting
              $delhi_only = $product->getData('delhi_only');
              return (int)$delhi_only;
          }
          /**
           * Do you logic that determines if we are prohibiting shipping
           * @param $quote
           */
           private function _checkDehliShippingAddress( $quote ){
           // Get the shipping address from the quote
           $shipping_address   = $quote->getShippingAddress();
           /**
            * I would suggest better validation than this but hopefully this will give you an idea on how to proceed.
            */
              $city               = trim(strtolower($shipping_address->getData('city')));
              // check if the city is dehli and if so return true
              if(($city == 'dehli')){
                  // return true so we know its OK to proceed
                  return true; 
              }else{
                  // This is not a match, return false so we know that its not allowed
                  return false;
              }
          }
      

      Here are some screen shots that may help Setting up the custom Product attribute enter image description here

    Now the label for the custom product attribute enter image description here

    Don't forget to assign this new product attribute to an attribute set.

    Now edit a product that belongs to this attribute set and our new product attribute enter image description here

    Now, we can test the frontend experience During checkout, once that address is saved and we have all the information required to make our final validation that things are ok to proceed or stop them and return them to the cart with the error: enter image description here

    We found an item in the cart that stops checkout take them back to the cart with the error message enter image description here