4

I am trying to edit Order that includes the below possible cases:

  • Update Order Item Price
  • Increse Order Item Qty Or Cancel Order Item Qty
  • Add New Item into Order

For Adding new Item in Order, I am following the below Way:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order = $this->_orderFactory->load('3445');
$order = $objectManager->create('Magento\Sales\Model\Order')->load($orderId);

$quote = $objectManager->create('\Magento\Quote\Model\Quote')->load($order->getQuoteId());

$productId = 4272;
$productQty = 2;

$product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);

//Adding New Item into Quote
$objectManager->create('Magento\Quote\Model\Quote\Item')
                ->setProduct($product)
                ->setQuote($quote)
                ->setQty($productQty)
                ->save();

//Quote Address Update
$shippingData = $order->getShippingAddress()->getData();
$quoteAddress = $quote->getShippingAddress();
$shippingData['address_id'] = $quoteAddress->getAddressId();
$quoteAddress->setData($shippingData);
$quoteAddress->save();

$billingData = $order->getBillingAddress()->getData();
$quoteAddress = $quote->getBillingAddress();
$billingData['address_id'] = $quoteAddress->getAddressId();
$quoteAddress->setData($billingData);
$quoteAddress->save();        

//Quote Collect Totals
$quote->getShippingAddress()
        ->setShippingMethod($order->getShippingMethod())
        ->setCollectShippingRates(true);
$quote->setTotalsCollectedFlag(false)->collectTotals();
$quote->save();

then I am planning to add this new Quote Item to convert into Order Item. But using the above code, All Quote Items are deleted and all grand total and subtotal in quote set to 0.

My question is: What is correct way to modify the existing Order ?

Like in sales_order_item table we have the field qty_canceled, Using the below code I can cancel the complete Item ordered qty. But when I am saving the order, Subtotal and Grand total all are set to 0.

$order = $this->_orderFactory->load('3432');
if ($order->canCancel()) {
    $orderItems = $order->getAllItems();        
    foreach ($orderItems as $item) {
        if($item['product_id']==3341) {    

            $item->setQtyCanceled($item['qty_ordered']);
            $item->save();  
        }
    }
    $order->save();
}
  • 2
    I have not read your code in detail, but on a general level: From a business logic standpoint editing an existing order should be restricted / avoided as it is tied to accounting / book keeping. Respecting accounting standards, the correct way is to create some kind of order that will adjust the existing order (cancel, add, change price etc). – user5198077 Feb 1 '18 at 10:24
  • Yes I understand but as per application logic its required – Pankaj Pareek Feb 5 '18 at 9:02
1

In my experience it is possible to edit the billing address, shipping address, or status of an order.

For all other actions you would have to cancel and reissue the order. When you edit an order it will append a number to the order number.

What would be the problem with changing the order number from NNNNN to NNNNN-1?

0

My question is: What is correct way to modify the existing Order ?

I don't think there is one as that breaks business logic as stated in comments.

Anyway Magento\Sales\Model\Order has a public function addItem(\Magento\Sales\Model\Order\Item $item). I'd try that one.

  • yes using addItem function, I am able to add product into existing order. But before that I want to add product in existing quote and adding new product in quote remove existing products in quote. – Pankaj Pareek Feb 6 '18 at 5:53
  • Try using addProduct of Quote class? – steros Feb 6 '18 at 7:31
  • Yes tried using $quote->addProduct($product, $qty); and $objectManager->create('Magento\Quote\Model\Quote\Item')->setProduct($product)->setQuote($quote)->setQty($productQty)->save() using Quote Item also – Pankaj Pareek Feb 6 '18 at 8:59
  • Then that's because it's inherent logic. I didn't look at the code in detail though. It would mean you need to code it yourself or change the core code so it doesn't delete it. – steros Feb 6 '18 at 9:12
  • I think you should look at magento's default functionality implemented to create admin order. Take a look at class Magento\Sales\Controller\Adminhtml\Order\Create. – Gulshan Maurya Feb 9 '18 at 12:54
0

I would totally disencourage you to do that. But if you want to know how JUST in terms of learning

That being said

Take a look into these interfaces

Magento\Sales\Api\OrderRepositoryInterface

and

Sales\Api\OrderItemRepositoryInterface

You can use save, delete and so on, in order to achieve whatever you want. But I am pretty sure that this is not going to work properly.

Cheers,

  • Thanks for your answer. But I am trying the code in standalone script. I already checked the repository. but here my questions is how to modify the existing quote because modifying that remove the old items – Pankaj Pareek Feb 9 '18 at 16:05
  • Handle all this is stuff is very complicated. I am not sure if Magento was designed to handle this kind of behaviour. You can take a look at the Quote Interfaces as well. Good luck! – Thiago Lima Feb 9 '18 at 17:16
0

For update Order Data (price,discount,etc) you need to update qoute after add product/s somtiling like:

$quote->collectTotals()->save(); 
$order->setSubtotal($quote->getSubtotal())
        ->setBaseSubtotal($quote->getBaseSubtotal())
        ->setGrandTotal($quote->getGrandTotal())
        ->setBaseGrandTotal($quote->getBaseGrandTotal());
    $quote->save();
0

If you would like to modify orders, you should update quote and order.

Edit items:

$item = $quote->getItemById($id);
    if(!$item) return;

    $taxAmount = $item->getTaxPercent() * $qty * ($item->getProduct()->getPrice()/100);
    $rowTotalInclTax = $item->getPrice() * $qty + $taxAmount;
    $item
        ->setQty($qty)
        ->setTaxAmount($taxAmount)
        ->setRowTotalInclTax($rowTotalInclTax);
    $existData = $order->getItemByQuoteItemId($item->getId());
    $orderItem = $this->toOrderItem->convert($item);
    $existData->addData($orderItem->getData());

Remove items:

foreach ($quote->getAllVisibleItems() as $quoteItem) {
        if ($id == $quoteItem->getId()){
            $quoteItem->delete();
            $quote->collectTotals();

            foreach ($order->getItemsCollection() as $orderItem){
                if($orderItem->getQuoteItemId() == $id){
                    $this->orderItemRepository->deleteById($orderItem->getId());
                }
            }
        }
    }

Add new Items:

$product = $this->productRepository->getById($productId);
    if(!$product) return;

    $params = [
        'product'   => $productId,
        'qty'       => $qty
    ];
    $request = new \Magento\Framework\DataObject();
    $request->setData($params);
    $quote->addProduct($product, $request);
    $quote->collectTotals();

    foreach ($quote->getAllVisibleItems() as $item){
        if($productId == $item->getProduct()->getId()){
            /**
             * collect item price
             */
            $item->save();
            $existData = $order->getItemByQuoteItemId($item->getId());
            $orderItem = $this->toOrderItem->convert($item);

            if ($existData) {
                $existData->addData($orderItem->getData());
            }else{
                /**
                 * add new product to
                 */
                if ($item->getParentItem()) {
                    $item->setParentItem(
                        $order->getItemByQuoteItemId($item->getParentItem()->getId())
                    );
                }
                $order->addItem($orderItem);
            }
        }
    }

Pls visit my link as an example tutorial modify exist an order.

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.