My Problem:
I want to use observer before checkout onepage page begins, in that, based on products in the cart, I want to disable shipping if it doesn't match certain conditions.
I am using [controller_action_predispatch_checkout_onepage_index] event observer, this basically call before checkout page starts loading...I am able to get all products and quote info but didn't found any method to disable shipping.
What I am looking for,
from the observer, is it possible to disable shipping by calling certain magento methods or any other solutions?
Overriding collectRates()
After getting few replies, I am trying to override collectRates() method using code given below
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('flatrate');
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod('flatrate');
$method->setMethodTitle($this->getConfigData('name'));
if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
$shippingPrice = '0.00';
}
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
$result->append($method);
Although, I dont want to enable flatrate shipping method either. I just want to disable shipping, or optionally return with reply something like
Free shipping $0.00
User can select that to continue to next step. Please help me from here..
What should I use in $method->setCarrier('??????');
or what changes I do need to do in above code?
I think it might be better to either override or subclass the individual Carrier models.
All carriers implement a method "Mage_Shipping_Model_Carrier_Abstract::collectRates()" to return results.
It is possible to get information about the current quote to modify the returned rates/options from within this method.
That said, if there is a way to do it with an observer, it would probably be cleaner/easier.
Finally I have override shipping method, its a two step code but you can reduce it to one step if you wish. Here is my two step solution.
Before we start our shipping class needs to extend and implement
extends Mage_Shipping_Model_Carrier_Abstract
implements Mage_Shipping_Model_Carrier_Interface
Now, We create a protected method
protected function _createMethod($request, $method_code, $title, $price, $cost)
{
$method = Mage::getModel('shipping/rate_result_method');
$method->setCarrier('australiapost'); // in my case its australia post, it can be any other whatever you are using
$method->setCarrierTitle($this->getConfigData('title'));
$method->setMethod($method_code);
$method->setMethodTitle($title);
$method->setPrice($this->getFinalPriceWithHandlingFee($price));
$method->setCost($cost);
return $method;
}
Now just use code below to create new method with free shipping and bypass existing shipping calculator, this code will go inside collectRates(Mage_Shipping_Model_Rate_Request $request) method
// PROCESS WILL RETURN FREE SHIPPING
if ($request->getFreeShipping() === true || $request->getPackageQty() == $this->getFreeBoxes()) {
$shippingPrice = '0.00';
}
$shipping_method = 'Free Shipping';
$method = $this->_createMethod($request, $shipping_method, 'Shipping Disabled', '0.00', '0.00');
$result->append($method);
return $result;
By Doing this, you can get result like below in checkout and user can easily click continue to next step.
Shipping Disabled $0.00
Related
In magento checkout page, after giving billing information and shipping information, i understand that these details are sending to fedex then the shipping rates are populating in chekout page, before sending theses details to fedex, i want to change the weight of the product, i Want to add additional weights for each products,
suppose user adding a product with weight of 2 pounds, i want to send
these weight to 2*5 = 10pounds, how can i do that in magento? please
help.
Not sure to understand what you want exactly but I'll give a try.
I think you can override Mage_Checkout_OnepageController::savePaymentAction method in your local pool and in your local method, dispatch your own new event 'save_payment_action_before' and pass your objects as parameters.
In your fedex module, create an observer, get your object and change the order weight before it's sent to fedex.
To create your custom event, check this post
Finally i find out that it is happening in the sales/quote/item.php file, there is a function called setProduct, here we need to add addititonal info while setting data.
public function setProduct($product)
{
$batchQty = Mage::getModel('catalog/product')->load($product->getId())->getBatchQty();
$roleId = Mage::getSingleton('customer/session')->getCustomerGroupId();
$userrole = Mage::getSingleton('customer/group')->load($roleId)->getData('customer_group_code');
$userrole = strtolower($userrole);
if ($this->getQuote()) {
$product->setStoreId($this->getQuote()->getStoreId());
$product->setCustomerGroupId($this->getQuote()->getCustomerGroupId());
}
if($userrole=="retailer" && $batchQty>0 ){
$this->setData('product', $product)
->setProductId($product->getId())
->setProductType($product->getTypeId())
->setSku($this->getProduct()->getSku())
->setName($product->getName())
->setWeight($this->getProduct()->getWeight()*$batchQty)
->setTaxClassId($product->getTaxClassId())
->setBaseCost($product->getCost())
->setIsRecurring($product->getIsRecurring());
} else {
$this->setData('product', $product)
->setProductId($product->getId())
->setProductType($product->getTypeId())
->setSku($this->getProduct()->getSku())
->setName($product->getName())
->setWeight($this->getProduct()->getWeight())
->setTaxClassId($product->getTaxClassId())
->setBaseCost($product->getCost())
->setIsRecurring($product->getIsRecurring());
}
if ($product->getStockItem()) {
$this->setIsQtyDecimal($product->getStockItem()->getIsQtyDecimal());
}
Mage::dispatchEvent('sales_quote_item_set_product', array(
'product' => $product,
'quote_item' => $this
));
return $this;
}
I've created an observer for customer_registration_success, but I need to listen to the event that is triggered on one page checkout, when a user chooses to register. http://cl.ly/image/2F3L0s1E3g1e
Any thoughts on what event this might be?
You could create your own 'custom event' using the logic below to check which method they use to check out on success.phtml or incorporate it in sales_order_place_after
$quoteId = Mage::getModel('sales/order')->loadByIncrementId($this->getOrderId())->getQuoteId();
$quote = Mage::getModel('sales/quote')->load($quoteId);
$method = $quote->getCheckoutMethod(true);
if ($method == 'register'){
//the customer registered...do your stuff
}
Source : http://www.magentocommerce.com/boards/viewthread/273690/#t375160
I've been searching, trying, and failing alot here. What I want is to add a checkbox, on the Shipping page of Onepage checkout, the standard magento checkout.
I want to create a checkbox so that customers can check it if they want their products to be placed on their address without a signature.
I've been messing around with some old "Accept Terms" checkboxes, but with no luck.
I'm hoping that somebody might have had to make the same kind of customization.
What you can do is save the preference in the checkout/session via an observer. First, add the checkbox to the shipping section and give it the property of name=shipping[no_signature]. Then, create a new module and hook into the event controller_action_postdispatch_checkout_onepage_saveShipping and then use this code:
public function controller_action_postdispatch_checkout_onepage_saveShipping($observer)
{
$params = (Mage::app()->getRequest()->getParams()) ? Mage::app()->getRequest()->getParams() : array();
if (isset($params['shipping']['no_signature']) && $params['shipping']['no_signature']) {
Mage::getSingleton('checkout/session')->setNoSignature(true);
} else {
Mage::getSingleton('checkout/session')->setNoSignature(false);
}
return $this;
}
Then, when the order is about to be placed, hook into the event sales_order_place_before you can add a comment to the order like this:
public function sales_order_place_before($observer)
{
$order = $observer->getOrder();
if (Mage::getSingleton('checkout/session')->getNoSignature()) {
$order->setCustomerNote('No signature required.');
} else {
$order->setCustomerNote(null);
}
return $this;
}
When you go to Sales > Orders, you should see a comment on the order regarding if the customer requires a signature or not. This is under the assumption that no other module or custom code is injecting anything into the customer_note field on the order object.
I have an extremely simple module that allows a customer to "Purchase On Account". The module doesn't do anything special really (it was simply modified from a Cash On Delivery module.)
The problem is I only want to offer this payment method to logged in customers.
So far my module looks like this:
BuyOnAccount/
etc/
config.xml
system.xml
Model/
PaymentMethod.php
The content of PaymentMethod.php is:
class MyCompany_BuyOnAccount_Model_PaymentMethod extends Mage_Payment_Model_Method_Abstract
{
protected $_code = 'buyonaccount';
protected $_isInitializeNeeded = true;
protected $_canUseInternal = false;
protected $_canUseForMultishipping = false;
}
The config and system xml files contain the usual sort of thing (please let me know if you would like to see the code and i'll edit)
So bascically I need to disable the module if the user is not logged in (but obviously only for the current customer session!)
Any ideas?
Thanks
You can just add a method to your payment model called isAvailable(Mage_Sales_Model_Quote $quote) that returns a bool. For example, in your situation you could add something like:
public function isAvailable($quote = null) {
$isLoggedIn = Mage::helper('customer')->isLoggedIn();
return parent::isAvailable($quote) && $isLoggedIn;
}
The Mage_Payment_Model_Method_Free payment method that ships with Magento is an example of a payment method that employs this -- it'll only show if the basket total is zero.
I want to be able to toggle what shipping method is used based upon the items that are in the cart. Where is the best place to "check" this and grab the right shipping method?
The way it will work is that there will be a standard shipping method that is used, and then, if there are certain items in the cart another method will override that other method.
I think I could do this by hacking around in the individual shipping modules, but I'd like to do this the "right" way.
shipping methods have built in method in Mage_Shipping_Model_Carrier_Abstract that they all extend:
public function isActive();
extend your shipping methods and add your logic to that method and don't forget to call parent::isActive(); first
Try and Try as I did to implement a custom override, I was only able to find success when I copied the entire Tablerates.php file to local/Mage/Shipping/Model/Carrier/Tablerates.php
isActive() was still not "the way" at that point. I had to introduce some code in the collectRates() function like so:
// check the store
if (Mage::app()->getStore()->getId() == 2){
// check for free shipping
$packageValue = $request->getPackageValueWithDiscount();
$freeShipping = ($request->getFreeShipping()) || ($packageValue >= Mage::getStoreConfig("carriers/freeshipping/free_shipping_subtotal", $this->getStore()));
if($freeShipping)
return false;
$foundFlag = false;
foreach ($request->getAllItems() as $item) {
$org_product = Mage::getModel('catalog/product')->load($item->getProductId());
if($org_product->getDeliveryFlag() == "workstationmats")
{
$foundFlag = true;
}
}
if ($foundFlag == false)
return false;
}
// end shpping mod
This was placed right at the beginning of the collectRates function.