Skip to content

Commit 3de58cd

Browse files
authored
Preserve manual discount when manually editing an order (#60240)
* Only recalculate coupons when real coupon is applied, not when manual discount is used * Add changelog * Add test * Update test This reverts 04db67b because now that the recalculation is not called, tax (additional $20) is also not shown * Better method to fetch coupons
1 parent d0ddb0d commit 3de58cd

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fix
3+
4+
Preserve manual discount when manually editing an order

plugins/woocommerce/includes/admin/wc-admin-functions.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,14 @@ function wc_save_order_items( $order_id, $items ) {
454454
}
455455

456456
$order->update_taxes();
457-
$order->recalculate_coupons();
457+
458+
// Only recalculate when a coupon is applied.
459+
// This allows manual discounts to be preserved when order items are saved.
460+
$order_coupons = $order->get_coupons();
461+
if ( ! empty( $order_coupons ) ) {
462+
$order->recalculate_coupons();
463+
}
464+
458465
$order->calculate_totals( false );
459466

460467
// Inform other plugins that the items have been saved.

plugins/woocommerce/tests/e2e-pw/tests/order/create-order.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ test.describe(
414414
)
415415
).toBeVisible();
416416
await expect(
417-
page.locator( 'table' ).filter( { hasText: 'Paid: $220.00' } )
417+
page.locator( 'table' ).filter( { hasText: 'Paid: $200.00' } )
418418
).toBeVisible();
419419
} );
420420

plugins/woocommerce/tests/legacy/unit-tests/discounts/discounts.php

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,8 +1691,6 @@ public function test_is_coupon_valid_fixed_product_sale_items() {
16911691

16921692
/**
16931693
* Test that fixed cart discount coupons maintain their total amount when quantities change in admin orders.
1694-
*
1695-
* @link https://github.com/woocommerce/woocommerce/issues/XXXXX
16961694
*/
16971695
public function test_fixed_cart_discount_quantity_change_admin_order() {
16981696
$price = 20;
@@ -1747,4 +1745,45 @@ public function test_fixed_cart_discount_quantity_change_admin_order() {
17471745
// Verify order total is $30 (original $40 - $10 discount).
17481746
$this->assertEquals( 30.0, $order->get_total(), 'Order total should be $30 after quantity change' );
17491747
}
1748+
1749+
/**
1750+
* Test that manual discounts are preserved when no coupons are used in order.
1751+
* This tests the logic in wc_save_order_items that only recalculates coupons when coupons exist.
1752+
*/
1753+
public function test_manual_discount_preservation_no_coupons() {
1754+
$price = 20;
1755+
1756+
// Create a product with a price of $20.
1757+
$product = WC_Helper_Product::create_simple_product();
1758+
$product->set_regular_price( $price );
1759+
$product->save();
1760+
$this->store_product( $product );
1761+
1762+
// Create an order.
1763+
$order = new WC_Order();
1764+
$order->set_status( 'processing' );
1765+
$order->save();
1766+
$order_item_id = $order->add_product( $product, 1 );
1767+
$this->store_order( $order );
1768+
1769+
// Simulate $5 manual discount.
1770+
$items = array(
1771+
'order_item_id' => array( $order_item_id ),
1772+
'line_total' => array( $order_item_id => $price - 5 ),
1773+
'line_subtotal' => array( $order_item_id => $price ),
1774+
);
1775+
1776+
// Save the order items - this should preserve manual discounts since no coupons are applied.
1777+
wc_save_order_items( $order->get_id(), $items );
1778+
1779+
// Reload the order to get updated data.
1780+
$order = wc_get_order( $order->get_id() );
1781+
$order_items = $order->get_items();
1782+
$order_item = reset( $order_items );
1783+
1784+
// Verify the manual discount is preserved.
1785+
$this->assertEquals( 20.0, $order_item->get_subtotal(), 'Subtotal should be $20' );
1786+
$this->assertEquals( 15.0, $order_item->get_total(), 'Total should be $15 preserving manual discount' );
1787+
$this->assertEquals( 15.0, $order->get_total(), 'Order total should be $15 preserving manual discount' );
1788+
}
17501789
}

0 commit comments

Comments
 (0)