Magento order split through observer - magento

I was wondering if we can split the order on onepage checkout before placing the order? And I want to do it Through observer.
I am using sales_order_place_before event to get the quote and split order.
I have tried to do it in observer like:
$productids=array(1,2);
$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();
// Start New Sales Order Quote
$quote = Mage::getModel('sales/quote')->setStoreId($store->getId());
// Set Sales Order Quote Currency
$quote->setCurrency($order->AdjustmentAmount->currencyID);
$customer = Mage::getModel('customer/customer')
->setWebsiteId($websiteId)
->loadByEmail($email);
if($customer->getId()==""){
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname('Jhon')
->setLastname('Deo')
->setEmail($email)
->setPassword("password");
$customer->save();
}
// Assign Customer To Sales Order Quote
$quote->assignCustomer($customer);
// Configure Notification
$quote->setSendCconfirmation(1);
foreach($productsids as $id){
$product=Mage::getModel('catalog/product')->load($id);
$quote->addProduct($product,new Varien_Object(array('qty' => 1)));
}
// Set Sales Order Billing Address
$billingAddress = $quote->getBillingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => 'john',
'middlename' => '',
'lastname' =>'Deo',
'suffix' => '',
'company' =>'',
'street' => array(
'0' => 'Noida',
'1' => 'Sector 64'
),
'city' => 'Noida',
'country_id' => 'IN',
'region' => 'UP',
'postcode' => '201301',
'telephone' => '78676789',
'fax' => 'gghlhu',
'vat_id' => '',
'save_in_address_book' => 1
));
// Set Sales Order Shipping Address
$shippingAddress = $quote->getShippingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => 'john',
'middlename' => '',
'lastname' =>'Deo',
'suffix' => '',
'company' =>'',
'street' => array(
'0' => 'Noida',
'1' => 'Sector 64'
),
'city' => 'Noida',
'country_id' => 'IN',
'region' => 'UP',
'postcode' => '201301',
'telephone' => '78676789',
'fax' => 'gghlhu',
'vat_id' => '',
'save_in_address_book' => 1
));
if($shipprice==0){
$shipmethod='freeshipping_freeshipping';
}
// Collect Rates and Set Shipping & Payment Method
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod('flatrate_flatrate')
->setPaymentMethod('checkmo');
// Set Sales Order Payment
$quote->getPayment()->importData(array('method' => 'checkmo'));
// Collect Totals & Save Quote
$quote->collectTotals()->save();
// Create Order From Quote
$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$increment_id = $service->getOrder()->getRealOrderId();
// Resource Clean-Up
$quote = $customer = $service = null;
// Finished
return $increment_id;
But it is not proceeding further.
Any help with the observer code will be appreciated.
thanks

Here is what i have achieved until now
created new module
installation file
<?xml version="1.0"?>
<config>
<modules>
<PMTECH_Splitorder>
<active>true</active>
<codePool>local</codePool>
<version>0.1.0</version>
</PMTECH_Splitorder>
</modules>
</config>
and here is the config.xml
<?xml version="1.0"?>
<config>
<modules>
<PMTECH_Splitorder>
<version>0.1.0</version>
</PMTECH_Splitorder>
</modules>
<global>
<helpers>
<splitorder>
<class>PMTECH_Splitorder_Helper</class>
</splitorder>
</helpers>
<models>
<splitorder>
<class>PMTECH_Splitorder_Model</class>
<resourceModel>splitorder_mysql4</resourceModel>
</splitorder>
<checkout>
<rewrite>
<type_onepage>PMTECH_Splitorder_Model_Checkout_Type_Onepage</type_onepage>
</rewrite>
</checkout>
</models>
</global>
</config>
look at the rewrite
<checkout>
<rewrite>
<type_onepage>PMTECH_Splitorder_Model_Checkout_Type_Onepage</type_onepage>
</rewrite>
</checkout>
Bellow is the final thing, the extended function
<?php
class PMTECH_Splitorder_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{
/**
* Create order based on checkout type. Create customer if necessary.
*
* #return Mage_Checkout_Model_Type_Onepage
*/
public function saveOrder()
{
$this->validate();
$isNewCustomer = false;
switch ($this->getCheckoutMethod()) {
case self::METHOD_GUEST:
$this->_prepareGuestQuote();
break;
case self::METHOD_REGISTER:
$this->_prepareNewCustomerQuote();
$isNewCustomer = true;
break;
default:
$this->_prepareCustomerQuote();
break;
}
$cart = $this->getQuote();
$key=0;
foreach ($cart->getAllItems() as $item)
{
$key= $key+1;
$temparray[$key]['product_id']= $item->getProduct()->getId();
$temparray[$key]['qty']= $item->getQty();
$cart->removeItem($item->getId());
$cart->setSubtotal(0);
$cart->setBaseSubtotal(0);
$cart->setSubtotalWithDiscount(0);
$cart->setBaseSubtotalWithDiscount(0);
$cart->setGrandTotal(0);
$cart->setBaseGrandTotal(0);
$cart->setTotalsCollectedFlag(false);
$cart->collectTotals();
}
$cart->save();
foreach ($temparray as $key => $item)
{
$customer_id = Mage::getSingleton('customer/session')->getId();
$store_id = Mage::app()->getStore()->getId();
$customerObj = Mage::getModel('customer/customer')->load($customer_id);
$quoteObj = $cart;
$storeObj = $quoteObj->getStore()->load($store_id);
$quoteObj->setStore($storeObj);
$productModel = Mage::getModel('catalog/product');
$productObj = $productModel->load($item['product_id']);
$quoteItem = Mage::getModel('sales/quote_item')->setProduct($productObj);
$quoteItem->setBasePrice($productObj->getFinalPrice());
$quoteItem->setPriceInclTax($productObj->getFinalPrice());
$quoteItem->setData('original_price', $productObj->getPrice());
$quoteItem->setData('price', $productObj->getPrice());
$quoteItem->setRowTotal($productObj->getFinalPrice());
$quoteItem->setQuote($quoteObj);
$quoteItem->setQty($item['qty']);
$quoteItem->setStoreId($store_id);
$quoteObj->addItem($quoteItem);
$quoteObj->setBaseSubtotal($productObj->getFinalPrice());
$quoteObj->setSubtotal($productObj->getFinalPrice());
$quoteObj->setBaseGrandTotal($productObj->getFinalPrice());
$quoteObj->setGrandTotal($productObj->getFinalPrice());
$quoteObj->setStoreId($store_id);
$quoteObj->collectTotals();
$quoteObj->save();
$this->_quote=$quoteObj;
$service = Mage::getModel('sales/service_quote', $quoteObj);
$service->submitAll();
if ($isNewCustomer) {
try {
$this->_involveNewCustomer();
} catch (Exception $e) {
Mage::logException($e);
}
}
$this->_checkoutSession->setLastQuoteId($quoteObj->getId())
->setLastSuccessQuoteId($quoteObj->getId())
->clearHelperData();
$order = $service->getOrder();
if ($order) {
Mage::dispatchEvent('checkout_type_onepage_save_order_after',
array('order'=>$order, 'quote'=>$quoteObj));
$quoteObj->removeAllItems();
$quoteObj->setTotalsCollectedFlag(false);
$quoteObj->collectTotals();
}
/**
* a flag to set that there will be redirect to third party after confirmation
* eg: paypal standard ipn
*/
$redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
/**
* we only want to send to customer about new order when there is no redirect to third party
*/
if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
try {
$order->sendNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
// add order information to the session
$this->_checkoutSession->setLastOrderId($order->getId())
->setRedirectUrl($redirectUrl)
->setLastRealOrderId($order->getIncrementId());
// as well a billing agreement can be created
$agreement = $order->getPayment()->getBillingAgreement();
if ($agreement) {
$this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
}
}
// add recurring profiles information to the session
$profiles = $service->getRecurringPaymentProfiles();
if ($profiles) {
$ids = array();
foreach ($profiles as $profile) {
$ids[] = $profile->getId();
}
$this->_checkoutSession->setLastRecurringProfileIds($ids);
// TODO: send recurring profile emails
}
Mage::dispatchEvent(
'checkout_submit_all_after',
array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
);
return $this;
}
}
NOTE this script still fails to split the order total, which i am working on and will update you once done
Here is the code on github, you are welcome to contribute

Related

Magento - Customer import slow - looking to optimise script

I have a cron that imports/updates 3000 customers everyday. This however takes approx 5 hours... I need to do this everyday so I'm trying to optimise my code for speed.
This is my current code:
// ~3000 customers
foreach($results as $customerRecord) {
// customer general data:
$customer = $customerModel;
$customer->setWebsiteId($websiteId);
$email = $customerRecord['cc_email'];
$password = $email; // set password same as email
$customer->loadByEmail($email);
$customer->setEmail($email);
$nameAr = explode(" ", $customerRecord['cc_name']);
$customer->setFirstname($nameAr[0]);
$customer->setLastname($nameAr[1]);
$customer->setPassword($password);
// custom attributes
$customer->setCustomerFromOw("Yes");
$customer->setCdOwAccount($customerRecord['cd_ow_account']);
$customer->setDiscountStructureName($customerRecord['discount_structure_name']);
$customer->setPriceListName($customerRecord['price_list_name']);
$customer->setCcdCreditLimit($customerRecord['ccd_credit_limit']);
$customer->setCcdtBalance($customerRecord['ccdt_balance']);
$customer->setAdditionalPriceLists($customerRecord['additional_price_lists']);
$customer->setOwDeliveryRates($customerRecord['ow_delivery_rates']);
// Netzarbeiter CustomerActivation - ensure set to true
$customer->setCustomerActivated(true);
try {
$customer->setConfirmation(null);
// Netzarbeiter CustomerActivation - ensure set to true
$customer->setCustomerActivated(true);
$customer->save();
}
catch (Exception $ex) {
Zend_Debug::dump($ex->getMessage());
Mage::log('FAIL: Customer with email '.$email.' - '.$ex->getMessage(), null, 'sulman.log');
}
// customer delivery address:
$_delivery_address = array (
'firstname' => $nameAr[0],
'lastname' => $nameAr[1],
'street' => array (
'0' => $customerRecord['cd_invoice_address1'],
'1' => $customerRecord['cd_invoice_address2']." ".$customerRecord['cd_invoice_address3'],
),
'city' => $customerRecord['cd_invoice_town'],
'region_id' => '',
'region' => $customerRecord['cd_invoice_county'],
'postcode' => $customerRecord['cd_invoice_postcode'],
'country_id' => $customerRecord['cd_invoice_country_code'],
'telephone' => $customerRecord['cd_invoice_telephone'],
'company'=> $customerRecord['cd_invoice_name'],
);
$customAddress = Mage::getModel('customer/address');
$customAddress->setData($_delivery_address)
->setCustomerId($customer->getId())
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
try {
$customAddress->save();
}
catch (Exception $ex) {
Zend_Debug::dump($ex->getMessage());
}
}
I really can't see any other way of doing this - but if anyone can see a way to optimise this I would appreciate it!
Thanks
Use AvS_FastSimpleImport module for import customer fast below is like for module.
https://github.com/avstudnitz/AvS_FastSimpleImport
You need to pass data in array format for import customers.
require_once 'src/app/Mage.php';
umask(0);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$data[] = array('firstname' => "test",
.....
);
try {
/** #var $import AvS_FastSimpleImport_Model_Import */
$import = Mage::getModel('fastsimpleimport/import');
$import->processCustomerImport($data);
} catch (Exception $e) {
print_r($import->getErrorMessages());
}

In magento, update customer entity if customer has at least one order

I have created a custom attribute is_buyer for user which will be set to 1 after order post event.
Now I want to set 'is_buyer' to 1 for old users which have at least one order.
I can do this using foreach loop but I want to do this with a single query.
Any body knows how to write query for mentioned task using magento.
I have already written one time script using loop.
<?php
set_time_limit(0);
$customers = Mage::getModel('customer/customer')
->getCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter(array(array('attribute' => 'is_buyer', 'null' => true)), '', 'left');
$orders = Mage::getSingleton('sales/order')->getCollection()
->addAttributeToSelect('customer_id');
foreach ($customers as $customer) {
$orders->addFieldToFilter('customer_id', $customer->getId());
if ($orders->count() > 0) {
$customer->setData('is_buyer', 1);
} else {
$customer->setData('is_buyer', 0);
}
$customer->save();
}
You can use this slow approach to set the old users one time. And use an observer
to set the customer information ad hoc for new orders. So you only need to run the above script once. You can actually do some performance tuning...save and load in foreach is bad practice, but as you only need to run the script one it might not matter...
$customers = Mage::getModel('customer/customer)->getCollection();
foreach ($customers as $_customer){
$_orders = Mage::getModel('sales/order')->getCollection()->addFieldToFilter('customer_id',$_customer->getId());
if ($_orders->count()){
$customer->setIsBuyer();
$customer->save();
}
}
The event is:
<sales_order_place_after>
<observers>
<your_observer>
<type>singleton</type>
<class>YOUR_CLASS</class>
<method>YOUR_METHOD</method>
</your_observer>
</observers>
</sales_order_place_after>
The actual observer method (proof of concept but slow):
public static function YOUR_METHOD($observer) {
$event = $observer->getEvent();
$order = $event->getOrder();
$order->getCustomerId();
$customer = Mage::getModel('customer/customer')->load($order->getCustomerId());
$customer->setIsBuyer();
$customer->save();
}
So here is installer code which can do this in one query instead of loop.
/** #var Mage_Customer_Model_Entity_Setup $setup */
$setup = $this;
$setup->startSetup();
$setup->addAttribute('customer', 'is_buyer', array(
'type' => 'int',
'input' => 'boolean',
'label' => 'Is Buyer',
'global' => 1,
'visible' => 1,
'required' => 0,
'user_defined' => 0,
'default' => '0',
'visible_on_front' => 0,
'position' => 200
));
$attributeId = $this->getAttributeId('customer', 'is_buyer');
$setup->run("
INSERT INTO customer_entity_int (`entity_type_id`, `attribute_id`, `entity_id`, `value`)
SELECT 1, {$attributeId}, c.entity_id, 1
FROM customer_entity c
WHERE c.entity_id IN (
SELECT s.customer_id FROM sales_flat_order s
WHERE s.customer_id IS NOT NULL
GROUP BY s.customer_id
)
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`);
");

Magento create order programmatically with downloadable product

I have been successful creating orders with a Custom controller and all works well. My issue is i need to add the ability to create orders with downloadable product. I would just like to be pointed on where to start.
Controller is handling all the set up and the order save. Is there a Action or something I need to hit for the customer to be able to access his/her downloads?
Try the below Code, please go threw comments.
<?php
require_once 'app/Mage.php';
Mage::app();
$customer = Mage::getModel("customer/customer")
->setWebsiteId(Mage::app()->getStore()->getWebsiteId())
->loadByEmail($data['email']);
if(!$customer->getId()) {
$customer->setEmail($email); //enter Email here
$customer->setFirstname($fname); //enter Lirstname here
$customer->setLastname($lname); //enter Lastnamre here
$customer->setPassword(password); //enter password here
$customer->save();
}
$storeId = $customer->getStoreId();
$quote = Mage::getModel('sales/quote')
->setStoreId($storeId);
$quote->assignCustomer($customer);
// add product(s)
$product = Mage::getModel('catalog/product')->load(186); //product id
/*$buyInfo = array(
'qty' => 1,
'price'=>0
// custom option id => value id
// or
// configurable attribute id => value id
);*/
$params = array();
$links = Mage::getModel('downloadable/product_type')->getLinks( $product );
$linkId = 0;
foreach ($links as $link) {
$linkId = $link->getId();
}
//$params['product'] = $product;
$params['qty'] = 1;
$params['links'] = array($linkId);
$request = new Varien_Object();
$request->setData($params);
//$quoteObj->addProduct($productObj , $request);
/* Bundled product options would look like this:
$buyInfo = array(
"qty" => 1,
"bundle_option" = array(
"123" => array(456), //optionid => array( selectionid )
"124" => array(235)
)
); */
//$class_name = get_class($quote);
//Zend_Debug::dump($class_name);
$quote->addProduct($product, $request);
$addressData = array(
'firstname' => 'Vagelis', //you can also give variables here
'lastname' => 'Bakas',
'street' => 'Sample Street 10',
'city' => 'Somewhere',
'postcode' => '123456',
'telephone' => '123456',
'country_id' => 'US',
'region_id' => 12, // id from directory_country_region table if it Country ID is IN (India) region id is not required
);
$billingAddress = $quote->getBillingAddress()->addData($addressData);
$shippingAddress = $quote->getShippingAddress()->addData($addressData);
/*$shippingAddress->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('flatrate_flatrate')
->setPaymentMethod('checkmo');*/
/* Free shipping would look like this: */
$shippingAddress->setFreeShipping( true )
->setCollectShippingRates(true)->collectShippingRates()
->setShippingMethod('freeshipping_freeshipping')
->setPaymentMethod('checkmo'); /* shipping details is not required for downloadable product */
$quote->setCouponCode('ABCD'); // if required
/* Make Sure Your Check Money Order Method Is Enable */
/*if the product value is zero i mean free product then the payment method is free array('method' => 'free')*/
$quote->getPayment()->importData(array('method' => 'checkmo'));
$quote->collectTotals()->save();
$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();
printf("Order Created Successfully %s\n", $order->getIncrementId());

Make an error message on Magento checkout page (Shipping Method stage)

I developed a Magento shipping method module and it works fine.
I can retrieve the list of available shipping methods from my remote service but I want to have an error message if something will be wrong with connection to the srvice or etc.
The code of collectRates carrier class is listed below.
public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
if (!$this->getConfigFlag('active')) {
return false;
}
require_once Mage::getBaseDir() . '/app/code/local/Citymail/CitymailDeliveryOption/lib/syvo_service_connect.php';
$citymail_service_url = $this->getConfigData('service_url') . '/syvo_service';
$connection = new syvo_service_connect($citymail_service_url);
if($connection->connect()) {
$handling = Mage::getStoreConfig('carriers/'.$this->_code.'/handling');
$rate_result = Mage::getModel('shipping/rate_result');
$product_qty = 0;
$products_data = array();
$currency = Mage::app()->getStore()->getCurrentCurrencyCode();
$quote = Mage::getSingleton('checkout/session')->getQuote();
foreach($quote->getAllVisibleItems() as $cartItem) {
$product_qty += $cartItem->getQty();
$products_data[$cartItem->getId()] = array(
'length_units' => 'cm',
'length' => 0,
'width' => 0,
'height' => 0,
'weight_units' => 'kg',
'weight' => $cartItem->getProduct()->getWeight(),
'shippable' => 'a',
'sell_price' => $cartItem->getProduct()->getPrice(),
'currency' => $currency,
);
}
$shipping_address = Mage::getModel('checkout/cart')->getQuote()->getShippingAddress();
$password = md5($this->getConfigData('service_password'));
$params = array(
'passw=' . $password,
'login=' . $this->getConfigData('service_login'),
'action=get_shipping_options',
'product_qty=' . $product_qty,
'products_data=' . json_encode($products_data),
'country=' . $shipping_address->getCountryId(),
'postal_code=' . $shipping_address->getPostcode(),
);
$response = $connection->send(implode('&', $params), 0, 30);
$response_status_line = $connection->getResponseStatusLine();
if((int)$response_status_line[1] == 403) {
//Access denied message
}
else {
$response_array = json_decode($response);
$citymail_service_points_data = array();
if($response_array->syvo_service_responce->type == 'success') {
$options = array();
foreach($response_array->syvo_service_responce->data->syvo_shipping_methods as $key_method => $shipping_method) {
$method_key = 'opt--' . $shipping_method->type . '--' . $shipping_method->distributor;
if($shipping_method->type == 'DHL_SERVICE_POINT') {
$citymail_service_points_data['service_points'][$shipping_method->id] = array(
'dhl_service_point_postcode' => $shipping_method->postcode,
'dhl_service_point_address' => $shipping_method->address,
);
$method_key .= '--' . $shipping_method->id;
}
$method = Mage::getModel("shipping/rate_result_method");
$method->setCarrier($this->_code);
$method->setCarrierTitle(Mage::getStoreConfig('carriers/' . $this->_code . '/title'));
$method->setMethod($method_key);
$method->setMethodTitle($shipping_method->text);
$method->setCost($shipping_method->rate);
$method->setPrice($shipping_method->rate + $handling);
$rate_result->append($method);
}
$street = $shipping_address->getStreet();
$citymail_temporary_order_data = array(
'login' => $this->getConfigData('service_login'),
'password' => $password,
'country_id' => $shipping_address->getCountryId(),
'company_name' => $shipping_address->getCompany(),
'name' => trim($shipping_address->getFirstname() . ' ' . $shipping_address->getLastname()),
'postal_code' => $shipping_address->getPostcode(),
'phone_number' => $shipping_address->getTelephone(),
'email' => $shipping_address->getEmail(),
'street' => $street[0],
'city' => $shipping_address->getCity(),
'matrix_id' => $response_array->syvo_service_responce->data->matrix_id,
'service_url' => $citymail_service_url,
);
$citymail_temporary_order_data = $citymail_service_points_data + $citymail_temporary_order_data;
Mage::getSingleton('core/session')->setCitymailTemporaryOrderData($citymail_temporary_order_data);
}
else {
//Some error handler
$error = Mage::getModel("shipping/rate_result_error");
$error->setCarrier('citymaildeliveryoption');
$error->setErrorMessage('sasasas');
$rate_result->append($error);
}
}
}
else {
}
return $rate_result;
}
This code has to return an error message if the module couldn't retrieve the list of shipping methods:
$error = Mage::getModel("shipping/rate_result_error");
$error->setCarrier('citymaildeliveryoption');
$error->setErrorMessage('sasasas');
$rate_result->append($error);
But the error is not displaying.
I checked an existing (core) Magento modules which use error handlers too (Ups, Usps modules) and error handlers of these modules also do not work, error message is not displaying.
Could you please advice some solution of this problem.
Tnank you!
Your code is good. You just need a little bit configuration for your carrier to always displays its methods.
Has shown in Mage_Shipping_Model_Shipping->collectCarrierRates() (line 176), Magento checks for 'showmethod' in your carrier config if a result is in error (and discard it, if it evaluates to 0) :
if ($carrier->getConfigData('showmethod') == 0 && $result->getError()) {
return $this;
}
So you just have to add this in your config.xml :
<?xml version="1.0" encoding="UTF-8"?>
<config>
<default>
<carriers>
<citymaildeliveryoption>
<showmethod>1</showmethod>
</citymaildeliveryoption>
</carriers>
</default>
</config>

Can shipping step and info be removed from checkout in Magento for a product with Free Shipping rule set?

For a specific product I've got a Shopping Cart Rule which makes shipping for it free. It would be logical to not show shipping information and bypass shipping method selection for such product. Is there any easy way to do this?
This can be easily accomplished with an extension module.
/app/etc/modules/YourCompany_SkipShipping.xml
<?xml version="1.0"?>
<config>
<modules>
<YourCompany_SkipShipping>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Checkout />
</depends>
</YourCompany_SkipShipping>
</modules>
</config>
/app/code/local/YourCompany/SkipShipping/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<YourCompany_SkipShipping>
<version>0.0.1</version>
</YourCompany_SkipShipping>
</modules>
<frontend>
<routers>
<checkout>
<modules before="Mage_Checkout">YourCompany_SkipShipping<modules>
</checkout>
</routers>
</frontend>
</config>
/app/code/local/YourCompany/SkipShipping/controllers/OnepageController.php
<?php
include "Mage/Checkout/controller/OnepageController.php"
class YourCompany_SkipShippingMethod_OnepageController
extends Mage_Checkout_OnepageController
{
public function saveBillingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost('billing', array());
$customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
if (isset($data['email'])) {
$data['email'] = trim($data['email']);
}
$result = $this->getOnepage()->saveBilling($data, $customerAddressId);
if (!isset($result['error'])) {
/* check quote for virtual */
if ($this->getOnepage()->getQuote()->isVirtual()) {
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
} elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
$method = $this->getAutoShippingMethod($data, $customerAddressId);
if (!empty($method)) {
$result = $this->getOnepage()->saveShippingMethod($method);
if(!$result) {
Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
'request'=>$this->getRequest(),
'quote'=>$this->getOnepage()->getQuote()
));
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
}
} else {
$result['goto_section'] = 'shipping_method';
$result['update_section'] = array(
'name' => 'shipping-method',
'html' => $this->_getShippingMethodsHtml()
);
$result['allow_sections'] = array('shipping');
$result['duplicateBillingInfo'] = 'true';
}
} else {
$result['goto_section'] = 'shipping';
}
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
public function saveShippingAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost('shipping', array());
$customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
$result = $this->getOnepage()->saveShipping($data, $customerAddressId);
if (!isset($result['error'])) {
$method = $this->getAutoShippingMethod($data, $customerAddressId);
if (!empty($method)) {
if(!$result) {
Mage::dispatchEvent('checkout_controller_onepage_save_shipping_method', array(
'request'=>$this->getRequest(),
'quote'=>$this->getOnepage()->getQuote()
));
$result['goto_section'] = 'payment';
$result['update_section'] = array(
'name' => 'payment-method',
'html' => $this->_getPaymentMethodsHtml()
);
}
} else {
$result['goto_section'] = 'shipping_method';
$result['update_section'] = array(
'name' => 'shipping-method',
'html' => $this->_getShippingMethodsHtml()
);
}
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
public function getAutoShippingMethod($data, $customerAddressId)
{
// This is where you put your code to process the cart/order for orders that can auto-select shipping method
// For now, skip
return '';
}
}
I'll leave the specifics of how you check the shipping method to you, but if you cannot figure it out, post a comment and I'll add that as well.
NB: All examples are based on Magento 1.5

Resources