Add/Remove order coupon actions logged in notes (#30642)
* log admin coupon code actions * added documentation, fixed return value * formatting * included user to note logs * Add changelog * Address PHPCS issues * Make WC_Abstract_Order::remove_coupon() return a bool * Move addition of coupon-related order notes from WC_Order to AJAX callbacks * Address PHPCS problems * Pass coupon order notes through `esc_html()` * Add AJAX update of notes when adding/removing coupons via admin * Fix tests (maybe?) --------- Co-authored-by: Jorge A. Torres <jorge.torres@automattic.com>
This commit is contained in:
parent
562fede1e2
commit
c8f7a564c5
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Log to order notes when coupons are removed or applied.
|
|
@ -488,6 +488,13 @@ jQuery( function ( $ ) {
|
|||
if ( response.success ) {
|
||||
$( '#woocommerce-order-items' ).find( '.inside' ).empty();
|
||||
$( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
|
||||
|
||||
// Update notes.
|
||||
if ( response.data.notes_html ) {
|
||||
$( 'ul.order_notes' ).empty();
|
||||
$( 'ul.order_notes' ).append( $( response.data.notes_html ).find( 'li' ) );
|
||||
}
|
||||
|
||||
wc_meta_boxes_order_items.reloaded_items();
|
||||
wc_meta_boxes_order_items.unblock();
|
||||
} else {
|
||||
|
@ -524,6 +531,13 @@ jQuery( function ( $ ) {
|
|||
if ( response.success ) {
|
||||
$( '#woocommerce-order-items' ).find( '.inside' ).empty();
|
||||
$( '#woocommerce-order-items' ).find( '.inside' ).append( response.data.html );
|
||||
|
||||
// Update notes.
|
||||
if ( response.data.notes_html ) {
|
||||
$( 'ul.order_notes' ).empty();
|
||||
$( 'ul.order_notes' ).append( $( response.data.notes_html ).find( 'li' ) );
|
||||
}
|
||||
|
||||
wc_meta_boxes_order_items.reloaded_items();
|
||||
wc_meta_boxes_order_items.unblock();
|
||||
} else {
|
||||
|
|
|
@ -1285,9 +1285,11 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
* Manual discounts are not affected; those are separate and do not affect
|
||||
* stored line totals.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @since 3.2.0
|
||||
* @since 7.6.0 Returns a boolean indicating success.
|
||||
*
|
||||
* @param string $code Coupon code.
|
||||
* @return void
|
||||
* @return bool TRUE if coupon was removed, FALSE otherwise.
|
||||
*/
|
||||
public function remove_coupon( $code ) {
|
||||
$coupons = $this->get_items( 'coupon' );
|
||||
|
@ -1299,9 +1301,12 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
$coupon_object = new WC_Coupon( $code );
|
||||
$coupon_object->decrease_usage_count( $this->get_user_id() );
|
||||
$this->recalculate_coupons();
|
||||
break;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1255,13 +1255,23 @@ class WC_AJAX {
|
|||
throw new Exception( __( 'Invalid coupon', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$order->remove_coupon( wc_format_coupon_code( wp_unslash( $coupon ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$code = wc_format_coupon_code( wp_unslash( $coupon ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
if ( $order->remove_coupon( $code ) ) {
|
||||
// translators: %s coupon code.
|
||||
$order->add_order_note( esc_html( sprintf( __( 'Coupon removed: "%s".', 'woocommerce' ), $code ) ), 0, true );
|
||||
}
|
||||
$order->calculate_taxes( $calculate_tax_args );
|
||||
$order->calculate_totals( false );
|
||||
|
||||
ob_start();
|
||||
include __DIR__ . '/admin/meta-boxes/views/html-order-items.php';
|
||||
$response['html'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$notes = wc_get_order_notes( array( 'order_id' => $order_id ) );
|
||||
include __DIR__ . '/admin/meta-boxes/views/html-order-notes.php';
|
||||
$response['notes_html'] = ob_get_clean();
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
wp_send_json_error( array( 'error' => $e->getMessage() ) );
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ class CouponsController {
|
|||
ob_start();
|
||||
include __DIR__ . '/../../../includes/admin/meta-boxes/views/html-order-items.php';
|
||||
$response['html'] = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
$notes = wc_get_order_notes( array( 'order_id' => $order->get_id() ) );
|
||||
include __DIR__ . '/../../../includes/admin/meta-boxes/views/html-order-notes.php';
|
||||
$response['notes_html'] = ob_get_clean();
|
||||
} catch ( Exception $e ) {
|
||||
wp_send_json_error( array( 'error' => $e->getMessage() ) );
|
||||
}
|
||||
|
@ -79,12 +84,16 @@ class CouponsController {
|
|||
$order->calculate_taxes( $calculate_tax_args );
|
||||
$order->calculate_totals( false );
|
||||
|
||||
$result = $order->apply_coupon( wc_format_coupon_code( wp_unslash( $coupon ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$code = wc_format_coupon_code( wp_unslash( $coupon ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$result = $order->apply_coupon( $code );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
throw new Exception( html_entity_decode( wp_strip_all_tags( $result->get_error_message() ) ) );
|
||||
}
|
||||
|
||||
// translators: %s coupon code.
|
||||
$order->add_order_note( esc_html( sprintf( __( 'Coupon applied: "%s".', 'woocommerce' ), $code ) ), 0, true );
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
|
|||
page.on( 'dialog', ( dialog ) => dialog.accept( couponCode ) );
|
||||
await page.click( 'button.add-coupon' );
|
||||
|
||||
await expect( page.locator( `text=${ couponCode }` ) ).toBeVisible();
|
||||
await expect( page.locator( '.wc_coupon_list li', { hasText: couponCode } ) ).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '.wc-order-totals td.label >> nth=1' )
|
||||
).toContainText( 'Coupon(s)' );
|
||||
|
@ -113,7 +113,7 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
|
|||
test( 'can remove a coupon', async ( { page } ) => {
|
||||
await page.goto( `/wp-admin/post.php?post=${ orderId }&action=edit` );
|
||||
// assert that there is a coupon on the order
|
||||
await expect( page.locator( `text=${ couponCode }` ) ).toBeVisible();
|
||||
await expect( page.locator( '.wc_coupon_list li', { hasText: couponCode } ) ).toBeVisible();
|
||||
await expect(
|
||||
page.locator( '.wc-order-totals td.label >> nth=1' )
|
||||
).toContainText( 'Coupon(s)' );
|
||||
|
@ -130,9 +130,7 @@ test.describe( 'WooCommerce Orders > Apply Coupon', () => {
|
|||
await page.dispatchEvent( 'a.remove-coupon', 'click' ); // have to use dispatchEvent because nothing visible to click on
|
||||
|
||||
// make sure the coupon was removed
|
||||
await expect(
|
||||
page.locator( `text=${ couponCode }` )
|
||||
).not.toBeVisible();
|
||||
await expect( page.locator( '.wc_coupon_list li', { hasText: couponCode } ) ).not.toBeVisible();
|
||||
await expect(
|
||||
page.locator( '.wc-order-totals td.label >> nth=1' )
|
||||
).toContainText( 'Order Total' );
|
||||
|
|
Loading…
Reference in New Issue