# Scheduled Percentage Sale on a Category

> Puts every product in chosen categories on sale by a percentage between two dates, with sale badges and crossed-out prices, without editing products.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, sale, categories, promotion
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-scheduled-category-sale/

## Code

```php
$wpide_cat_sale = array(
    'categories' => array( 'summer' ),   // Category slugs.
    'percent'    => 20,                  // Percent off the regular price.
    'from'       => '2026-07-01 00:00',  // Start (site timezone).
    'to'         => '2026-07-31 23:59',  // End.
);

$wpide_cat_sale_active = function ( $product ) use ( $wpide_cat_sale ) {
    $now = current_time( 'timestamp' );

    if ( $now < strtotime( $wpide_cat_sale['from'] ) || $now > strtotime( $wpide_cat_sale['to'] ) ) {
        return false;
    }

    $id = $product->get_parent_id() ? $product->get_parent_id() : $product->get_id();

    return has_term( $wpide_cat_sale['categories'], 'product_cat', $id );
};

$wpide_cat_sale_price = function ( $price, $product ) use ( $wpide_cat_sale, $wpide_cat_sale_active ) {
    $regular = (float) $product->get_regular_price( 'edit' );

    if ( $regular <= 0 || ! $wpide_cat_sale_active( $product ) ) {
        return $price;
    }

    $sale = round( $regular * ( 100 - $wpide_cat_sale['percent'] ) / 100, wc_get_price_decimals() );

    return ( '' === $price || $sale < (float) $price ) ? (string) $sale : $price;
};

foreach ( array( 'woocommerce_product_get_sale_price', 'woocommerce_product_get_price', 'woocommerce_product_variation_get_sale_price', 'woocommerce_product_variation_get_price', 'woocommerce_variation_prices_sale_price', 'woocommerce_variation_prices_price' ) as $wpide_hook ) {
    add_filter( $wpide_hook, $wpide_cat_sale_price, 50, 2 );
}

add_filter( 'woocommerce_get_variation_prices_hash', function ( $hash ) use ( $wpide_cat_sale ) {
    $now           = current_time( 'timestamp' );
    $hash['wpide'] = ( $now >= strtotime( $wpide_cat_sale['from'] ) && $now <= strtotime( $wpide_cat_sale['to'] ) ) ? 'sale-' . $wpide_cat_sale['percent'] : 'no-sale';

    return $hash;
} );
```

## Notes

Dates use the site's timezone, and products that already have a lower sale price keep it.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Scheduled Percentage Sale on a Category" 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/
