2

I created a custom charges on order for some specific products, Unfortunately custom charge was not updated in order total like cash on delivery,

Is there any way to update orders totals after order created without cancel order?

3 Answers 3

2

I think you can do this just like you would modify any other model instance.

$item = Mage::getModel('sales/order_item')->load(id here);
$item->setPrice(40)->setBasePrice(40)->save();

then

$order = Mage::getModel('sales/order')->load(order id here);
$order->setSubtotal(70)->setBaseSubtotal(70);
$order->setDiscountAmount(7)->setBaseDiscountAmout(7);
$order->setGrandTotal(63)->setBaseGrandTotal(63);
$order->save();

You might also need to change other values like tax, subtotal_incl_tax and others.

But this is a bad practice and you should not do it. It is better just to cancel the order and create a new one.

1
  • I was looking for Bulk order update, like COD was not there, That's why cancel order way not adopted, Thank you, Works for me. Commented Oct 7, 2016 at 4:54
5

Here I have created a solution to set custom item price and recalculate all the order totals.

We will need to calculate manually as the collectTotals will not work after an order is placed.

<?php
require_once('app/Mage.php'); //Path to Magento
umask(0);
Mage::app();
echo "<pre>";

$customProductPrice = 5; // Custom Product Price For One Quantity
$item = Mage::getModel('sales/order_item')->load(15); //Order Itemid
if($item): //Check item object exists or not
    $quantity = $item->getQtyOrdered();
    $rowTotal = $customProductPrice * $quantity;

    # calculateTaxAmount
    if (!empty($item->getTaxPercent())) {
        $taxAmount = ($rowTotal * $item->getTaxPercent()) / 100;
        $item->setTaxAmount($taxAmount)
            ->setBaseTax_amount($taxAmount);
    }

    #  Price In Grid Update
    $item->setPrice($customProductPrice)
        ->setBasePrice($customProductPrice);

    #Subtotal On Order * Qty
    $item->setRowTotal($rowTotal)
        ->setBaseRowTotal($rowTotal)
        ->setRowTotalInclTax($rowTotal)
        ->setBaseRowTotalInclTax($rowTotal);

    # Apply Item Discounted Amount (Recaculated Discount)
    if (!empty($item->getDiscountPercent())) {
        $discountedAmount = $item->getRowTotal()*$item->getDiscountPercent()/100;
        $item->setDiscountAmount($discountedAmount)
            ->setBaseDiscountAmount($discountedAmount);
    }
    $item->save();

    $order = Mage::getModel('sales/order')->load(11); //Orderid
    $orderSubTotal = 0;
    $orderBaseTax = 0;
    $orderDiscountAmount = 0;
    foreach ($order->getAllVisibleItems() as $_item) {
        $orderSubTotal += $_item->getBaseRowTotal();
        $orderBaseTax += $_item->getBaseTaxAmount() + $_item->getBaseHiddenTaxAmount();
        $orderDiscountAmount += $_item->getBaseDiscountAmount();
    }

    $grandTotal = ($orderSubTotal + $order->getShippingAmount() + $orderBaseTax) - $orderDiscountAmount;

    # Update Order Totals
    $order->setSubtotal($orderSubTotal)
        ->setBaseSubtotal($orderSubTotal)
        ->setDiscountAmount($orderDiscountAmount)
        ->setBaseDiscountAmount($orderDiscountAmount)
        ->setTaxAmount($orderBaseTax)
        ->setBaseTaxAmount($orderBaseTax)
        ->setGrandTotal($grandTotal)
        ->setBaseGrandTotal($grandTotal)
        ->save();
endif;
3
  • Thanks works perfectly Commented Aug 21, 2020 at 15:38
  • I converted this to magento2 if anyone needs it @ me, works perfectly!
    – Gaz Smith
    Commented Jul 16, 2021 at 7:56
  • @GazSmith Can you please share the Magento 2 code?
    – mechanic
    Commented Nov 15, 2022 at 13:55
0

In addition to the response from Ashish, I will add these changes before the $item->save();:

$orderAllItems = $order->getAllItems();
foreach ($orderAllItems as $item) {
        ...
        // Tax Amount
        $item->setRowInvoiced($taxAmount)
        ->setBaseTaxInvoiced($taxAmount);
        // Amount item without tax
        $item->setRowInvoiced($rowTotal)
        ->setBaseRowInvoiced($rowTotal);
        // Amount item with tax
        $totalWithTax = $rowTotal + $taxAmount;
        $item->setPriceInclTax($totalWithTax)
        ->setBasePriceInclTax($totalWithTax)
        ->setRowTotalInclTax($totalWithTax)
        ->setBaseAmountPaid($totalWithTax)
        ->setAmountPaid($totalWithTax)
        ->setBaseAmountOrdered($totalWithTax)
        ->setAmountOrdered($totalWithTax)
        ->setOriginalPrice($totalWithTax)
        ->setBaseOriginalPrice($totalWithTax)
        ;

        $item->save();
        ...

}
...

Also these changes before the $order->save();:

...
$order->setSubtotalInvoiced($orderSubTotal)
->setBaseSubtotalInvoiced($orderSubTotal)
->setBaseTaxInvoiced($orderBaseTax)
->setTaxInvoiced($orderBaseTax)
->setTotalPaid($grandTotal)
->setBaseTotalPaid($grandTotal)
->setTotalInvoiced($grandTotal)
->setBaseSubtotalInclTax($grandTotal)
->setSubtotalInclTax($grandTotal)
->setBaseTotalInvoiced($grandTotal)
->setBaseToGlobalRate($grandTotal)
->setBaseToOrderRate($grandTotal)
->setStoreToBaseRate($grandTotal)
->setStoreToOrderRate($grandTotal)
;
$order->save();

Otherwise you could keep old amounts in your order object, then elsewhere than in the order view. For instant the creditmemo form.

So here the final code if I modify Ashish code:

<?php
require_once('app/Mage.php'); //Path to Magento
umask(0);
Mage::app();
echo "<pre>";

$customProductPrice = 5; // Custom Product Price For One Quantity
$item = Mage::getModel('sales/order_item')->load(15); //Order Itemid
if($item): //Check item object exists or not
    $quantity = $item->getQtyOrdered();
    $rowTotal = $customProductPrice * $quantity;

# calculateTaxAmount
if (!empty($item->getTaxPercent())) {
    $taxAmount = ($rowTotal * $item->getTaxPercent()) / 100;
    $item->setTaxAmount($taxAmount)
        ->setBaseTax_amount($taxAmount)
        ->setTaxInvoiced($taxAmount)
        ->setBaseTaxInvoiced($taxAmount);
}

#  Price In Grid Update
$item->setPrice($customProductPrice)
    ->setBasePrice($customProductPrice);

#Subtotal On Order * Qty
$item->setRowTotal($rowTotal)
    ->setBaseRowTotal($rowTotal)
    ->setRowTotalInclTax($rowTotal)
    ->setBaseRowTotalInclTax($rowTotal)
    ->setRowInvoiced($rowTotal)
    ->setBaseRowInvoiced($rowTotal);

// Amount item with tax
$totalWithTax = $rowTotal + $taxAmount;
$item->setPriceInclTax($totalWithTax)
    ->setBasePriceInclTax($totalWithTax)
    ->setRowTotalInclTax($totalWithTax)
    ->setBaseAmountPaid($totalWithTax)
    ->setAmountPaid($totalWithTax)
    ->setBaseAmountOrdered($totalWithTax)
    ->setAmountOrdered($totalWithTax)
    ->setOriginalPrice($totalWithTax)
    ->setBaseOriginalPrice($totalWithTax);

# Apply Item Discounted Amount (Recaculated Discount)
if (!empty($item->getDiscountPercent())) {
    $discountedAmount = $item->getRowTotal()*$item->getDiscountPercent()/100;
    $item->setDiscountAmount($discountedAmount)
        ->setBaseDiscountAmount($discountedAmount);
}
$item->save();

$order = Mage::getModel('sales/order')->load(11); //Orderid
$orderSubTotal = 0;
$orderBaseTax = 0;
$orderDiscountAmount = 0;
foreach ($order->getAllVisibleItems() as $_item) {
    $orderSubTotal += $_item->getBaseRowTotal();
    $orderBaseTax += $_item->getBaseTaxAmount() + $_item->getBaseHiddenTaxAmount();
    $orderDiscountAmount += $_item->getBaseDiscountAmount();
}

$grandTotal = ($orderSubTotal + $order->getShippingAmount() + $orderBaseTax) - $orderDiscountAmount;

# Update Order Totals
$order->setSubtotal($orderSubTotal)
    ->setBaseSubtotal($orderSubTotal)
    ->setSubtotalInvoiced($orderSubTotal)
    ->setBaseSubtotalInvoiced($orderSubTotal)
    ->setDiscountAmount($orderDiscountAmount)
    ->setBaseDiscountAmount($orderDiscountAmount)
    ->setTaxAmount($orderBaseTax)
    ->setBaseTaxAmount($orderBaseTax)
    ->setBaseTaxInvoiced($orderBaseTax)
    ->setTaxInvoiced($orderBaseTax)
    ->setGrandTotal($grandTotal)
    ->setBaseGrandTotal($grandTotal)
    ->setTotalPaid($grandTotal)
    ->setBaseTotalPaid($grandTotal)
    ->setTotalInvoiced($grandTotal)
    ->setBaseSubtotalInclTax($grandTotal)
    ->setSubtotalInclTax($grandTotal)
    ->setBaseTotalInvoiced($grandTotal)
    ->setBaseToGlobalRate($grandTotal)
    ->setBaseToOrderRate($grandTotal)
    ->setStoreToBaseRate($grandTotal)
    ->setStoreToOrderRate($grandTotal)
    ->save();
endif;

Cheers, Axel

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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