# Bulk "Put on Sale" and "Remove Sale" Actions for Products

> Adds bulk actions to the Products list that put selected products on sale at a set percentage, or clear their sale prices, including all variations.

- Type: PHP
- Runs: Admin only
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, bulk-edit, sale, products
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-bulk-sale-actions/

## Code

```php
$wpide_bulk_sale_percent = 20; // Percent off the regular price.

add_filter( 'bulk_actions-edit-product', function ( $actions ) use ( $wpide_bulk_sale_percent ) {
    $actions['wpide_sale_on']  = sprintf( 'Put on sale (-%d%%)', $wpide_bulk_sale_percent );
    $actions['wpide_sale_off'] = 'Remove sale price';

    return $actions;
} );

add_filter( 'handle_bulk_actions-edit-product', function ( $redirect, $action, $ids ) use ( $wpide_bulk_sale_percent ) {
    if ( ! in_array( $action, array( 'wpide_sale_on', 'wpide_sale_off' ), true ) ) {
        return $redirect;
    }

    $changed = 0;

    foreach ( array_map( 'absint', (array) $ids ) as $id ) {
        $product = wc_get_product( $id );

        if ( ! $product || ! current_user_can( 'edit_product', $id ) ) {
            continue;
        }

        $targets = $product->is_type( 'variable' ) ? array_filter( array_map( 'wc_get_product', $product->get_children() ) ) : array( $product );

        foreach ( $targets as $target ) {
            $regular = (float) $target->get_regular_price( 'edit' );

            if ( 'wpide_sale_on' === $action && $regular > 0 ) {
                $target->set_sale_price( (string) round( $regular * ( 100 - $wpide_bulk_sale_percent ) / 100, wc_get_price_decimals() ) );
            } elseif ( 'wpide_sale_off' === $action ) {
                $target->set_sale_price( '' );
                $target->set_date_on_sale_from( null );
                $target->set_date_on_sale_to( null );
            }

            $target->save();
        }

        if ( $product->is_type( 'variable' ) ) {
            WC_Product_Variable::sync( $id );
        }

        $changed++;
    }

    return add_query_arg( 'wpide_sale_updated', $changed, $redirect );
}, 10, 3 );

add_action( 'admin_notices', function () {
    if ( isset( $_GET['wpide_sale_updated'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
        printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( sprintf( 'Sale prices updated on %d product(s).', absint( $_GET['wpide_sale_updated'] ) ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
    }
} );
```

## Notes

Set $wpide_bulk_sale_percent before use; sale prices are rounded to your store's decimals.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Bulk "Put on Sale" and "Remove Sale" Actions for Products" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
