Question

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();
Was it helpful?

Solution

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top