2

I want to create a quote from an existing order and remove some qtys and re apply the discounts. We need to work out the value of an order where we may cancel some of the items but not all.

I thought we could

  1. Get the order
  2. Convert to quote with modified Sku quantities
  3. Apply collect totals
  4. Get the new values
  5. Apply to the existing order in the system

I have converted the order but I get the following error on the method call addItem() to the Quote object -> please assume I have loaded the $order object by Id previous to this code snipped

Fatal error: Call to a member function getStoreId() on a non-object in /var/www/build-54/app/code/core/Mage/Sales/Model/Quote/Item/Abstract.php on line 65

    /** @var $converter \Mage_Sales_Model_Convert_Order */
    $converter = Mage::getModel('sales/convert_order');
    /** @var $quote \Mage_Sales_Model_Quote */
    $quote = $converter->toQuote($order);

    $items = $order->getAllVisibleItems();

    foreach($items as $item) {
        /** @var $item \Mage_Sales_Model_Order_Item */
        /** @var $quoteItem \Mage_Sales_Model_Quote_Item */
        $quoteItem = $converter->itemToQuoteItem($item);
        //var_dump($quoteItem);
        $quote->addItem($quoteItem);

    }

    $quote->collectTotals();
3

The proper way to add order items to a quote is as follows:

$cart = Mage::getSingleton('checkout/cart');
foreach ($order->getItemsCollection() as $item) {
    $cart->addOrderItem($item);
}

That takes care of checking product availability and applying any configuration options that might have been set originally.
If you don't want to use the cart since it's a singleton, check Mage_Checkout_Model_Cart::addOrderItem() and replicate that in your code.

Probably it's also a good idea to do a

$appEmulation = Mage::getSingleton('core/app_emulation');
$initialEnvironmentInfo = $appEmulation->startEnvironmentEmulation($quote->getStoreId());

before you work with it. Otherwise any emails sent might end up with the wrong locale. Revert back with $appEmulation->stopEnvironmentEmulation($initialEnvironmentInfo);

To save the quote, you could use $cart->save(), but that assumes a checkout session to be available. Probably better to use

$quote->collectTotals()->save();
  • It's worth noting that App Emulation didn't arrive until 1.5CE - svn.magentocommerce.com/source/branches/1.5/app/code/core/Mage/… – philwinkle Jun 12 '13 at 16:30
  • Thanks for looking at that! - I get the following though when passing in the order item : Fatal error: Uncaught exception 'Mage_Core_Exception' with message 'Please specify the product's option(s).' in /var/www/build-54/app/Mage.php:594 – Jonathan Tizard Jun 12 '13 at 16:35
  • I should say following the example of the cart singleton from what you have written - passing in the order item. – Jonathan Tizard Jun 12 '13 at 16:39
  • The order items should contain the info_buyRequest option which should contain all required options for a product. The error you specify happens if required options where added to a product after the original order (that is being reordered) was placed. – Vinai Jun 12 '13 at 17:05
  • The main issue is Magento doesn't do cancelled lines - its just cancels the whole order. I want to update an existing order programatically (pre dispatch) and re-adjust the qty's on that existing order. The issue is - I need to recalculate all the line totals etc again then save it back on the order. I thought if I could turn that existing order into a quote and recalculate it, I can use those values and put back over the original order. Then I just need to create a credit memo to refund the difference. So at this point the order has already happened. Make any sense? – Jonathan Tizard Jun 13 '13 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.