This works ok. The attributes are available in the eav_attributes table.
(2) Modify template
I modified the shipping template (available.phtml) for the delivery_time option. This works ok as well.
(3) Add an observer to save the attribute to the quote item
I added an observer for the checkout_controller_onepage_save_shipping_method event
with the following code:
/** * Fired from event "checkout_controller_onepage_save_shipping_method" * in Checkout/controllers/OnepageController.php: * * @param unknown_type $observer */
public function attachSpecialShippingAttribs($observer) { if($observer->getEvent()->getRequest()->isPost()) { $delivery_time = $observer->getEvent()->getRequest()->getPost('delivery_time', ''); $quote = $observer->getEvent()->getQuote(); $quote->setDeliveryTime($delivery_time); } }
I have managed to save my attributes to the quote object, but I am stiil stuck on saving the values to the order object. In order to get the attributes saved with the quote I added the attributes to the sales_flat_quote table:
<?php
$installer = $this; $installer->startSetup(); $setup = new Mage_Eav_Model_Entity_Setup('core_setup');
My attributes are saved to the quote object now (My initial sql setup file where I added the attributes the eav_attributes table is proably superfluous now(?)).
My next problem is that I can’t get the checkout process to save the new quote attributes to the order item. I am using another observer (sales_convert_quote_to_order) to save the additional attributes:
/** * Fired from event "sales_convert_quote_to_order" * in Sales/Model/Convert/Quote.php * * @param unknown_type $observer */
public function attachSpecialOrderAttribs($observer) { $event = $observer->getEvent(); $event->getOrder()->setDeliveryTime($event->getQuote()->getDeliveryTime); $event->getOrder()->setComments($event->getQuote()->getComments); }
you have to add your new attribute to the convert model for quote and order. you can do this by a extension of these models in your own module.
example for toOrder:
<?php /** * Magento * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://opensource.org/licenses/osl-3.0.php * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@magentocommerce.com so we can send you a copy immediately. * * @category Mage * @package Mage_Sofortueberweisung * @copyright Copyright (c) 2008 [m]zentrale GbR * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) */ class Mage_Leofino_Model_Convert_Quote extends Mage_Sales_Model_Convert_Quote {
/** * Convert quote model to order model * * @param Mage_Sales_Model_Quote $quote * @return Mage_Sales_Model_Order */
public function toOrder(Mage_Sales_Model_Quote $quote, $order=null) { $order = parent::toOrder($quote,$order); $order->setPreorder($quote->getPreorder());
return $order; }
/** * Convert quote payment to order payment * * @param Mage_Sales_Model_Quote_Payment $payment * @return Mage_Sales_Model_Quote_Payment */ public function paymentToOrderPayment(Mage_Sales_Model_Quote_Payment $payment) { $orderPayment = parent::paymentToOrderPayment($payment); $orderPayment->setPayAll($payment->getPayAll());
@[m] zentrale - Thank you again. My situation was different than jotu but your code helped me solve my problem.
I basically needed to add an order attribute called “is_downloaded” to flag the order if it has been downloaded. I simply extended the class “Mage_Sales_Model_Convert_Quote” like you suggested and added the following code:
The better way of doing this would be to use the config.xml to define your new fields as part of the fieldset that gets copied.
This method will prevent the need to write a custom class and override the magento one.
<?xml version="1.0"?>
<config>
<global>
<fieldsets> <!-- This shows converting a quote_item into an order_item The attribute code in differenct in both entities, so it translates for you --> <sales_convert_quote_item> <the_attribute_code_in_quote_item> <to_order_item>the_attribute_code_in_order_item</to_order_item> </the_attribute_code_in_quote_item> </sales_convert_quote_item>
<!-- This version uses '*' to indicate that the attribute name is the same It also show that you can convert an order_item attribute into several other entities --> <sales_convert_order_item> <the_attribute_code> <to_quote_item>*</to_quote_item> <to_invoice_item>*</to_invoice_item> <to_shipment_item>*</to_shipment_item> <to_cm_item>*</to_cm_item> </the_attribute_code> </sales_convert_order_item> </fieldsets>
I want to add a flag called is_gift to my onepage checkout flow. I have added a check box to the billing section template and created a new module with a controller that extends the onepage checkout controller and created a new action in there called saveBillingAction which get’s the value that was checked from the post and set’s it in the quote object. Then parent::saveBillingAction is called. This is all happening great so far.
I have followed the steps of adding eav attributes to the order and the quote and added similar code to my config.xml file as you have demonstrated above but changed sales_convert_quote_item to sales_convert_quote and to_order_item to to_order.
So far the copy doesn’t appear to be happening. In this particular thread, the steps have become out of order and I can’t find a decent wiki that does enough hand holding. Would you mind spending a few minutes and listing a sort of step by step for adding attributes to an order? I think it would help not only me, but everyone who wants to simply add something custom to the order object.
Hi - I should also add though that by default, the attributes that I added to the quote and order don’t show up by default when I dump the quote and order objects. I also manually edited the Mage_Sales_Model_Convert_Quote toOrder method just to see if I could copy the quote with the is_gift value over to the order but no joy. Nothing shows in an order dump called is_gift. So some step is being missed somewhere - I think I am missing the same step as the original author of this thread.
@Simon
I needed to create 3 input fields in the shipping method step in onepage and I follow the steps and the code sample by Simon and it helps a lot in my case.
@Lee
Thanks for the config method to convert quote model to sales model. It works really well.
It’s quite a challenge to create a seemingly simple field in onepage. The key is the config.xml file. My looks like this:
Hi,
Been following this thread & I’ve hit a problem - at the Place Order stage I’m getting an ‘undefined’ js error. I suspect that its due to a ) my syntax in the config.xml or b) an error in my actual code implementation
Here’s what I want to do: I want to take a custom product attribute and add this to the quote/order items so that I can display it in the invoice/shopping cart.
I’ve created my own module called Fws_AddArtistToOrder. Within my Helper I have the two following methods:
public function addArtistToQuote($observer) { $event = $observer ->getEvent(); $req = Mage::app()->getRequest(); $_items = $event->getQuote()->getItemsCollection(); foreach($_items as $_item) { if ($_item->getProduct() instanceof Mage_Catalog_Model_Product) { if (!$_item->getFwsArtist()) { try{ $_artist = Mage::getModel('catalog/product')->load($_item->getProduct()->getId())->getAttributeText('artist'); $_item->setFwsArtist(join(' ',array_reverse(explode(',',$_artist)) )); break; }catch(Exception $ex){ Mage::log("3a Fws_AddArtistToOrder_Helper_Data addArtistToQuote Exception " . $ex .' ',null,'eddie'.'.log'); } } } } }
/** * Listens for "sales_convert_quote_item_to_order_item" * Sets the order item artist to that of the quote item artist */ public function addArtistToOrder($observer) { $event = $observer->getEvent(); $orderItem = $event->getOrderItem(); $quoteItem = $event->getItem(); try{ $orderItem->setFwsArtist( $quoteItem->getFwsArtist() ); }catch(Exception $ex){ Mage::log("5a Fws_AddArtistToOrder_Helper_Data addArtistToOrder " . $ex . ' ',null,'eddie'.'.log'); } }
In the config.xml I reference these methods like so:
I know the first method, addArtistToQuote is being called, from the logs & the table sales_flat_quote_item, but the second method addArtistToOrder is not being called. I suspect that there is something about how I reference these methods that is leading the ‘undefined’ js error.
Any suggestions are most welcome!
I am also adding a new quote line amount and would like this to be visible on my orders as well. I was able to get the new amount onto my shopping cart (quote), but am unable to get this to the order.
My basic requirement is to add a new charge ‘liftgate service’ on the shipping method step of the checkout. Code I had used -
My quote gets the lift gate amount. But somehow this amount is not transferred to the order.
On debugging this, I checked
Mage_Sales_Model_Convert_Quote->addressToOrder
And found that the lift gate amounts are actually getting set on the Order object. But am wondering why these amounts aren’t getting saved onto the database table ‘sales_order’. Any suggestions? Also would setting this amount in ‘sales_order’ automatically display this new amount on order line of amounts?