# Stock Change History on Products

> Records every stock level change with the date and the person (or order) responsible, and shows the last 25 changes in a box on the product edit screen.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, inventory, stock, audit
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-stock-change-history/

## Code

```php
$wpide_stock_log_size = 25; // Entries kept per product.

$wpide_stock_log = function ( $product ) use ( $wpide_stock_log_size ) {
    if ( ! $product instanceof WC_Product || ! $product->managing_stock() ) {
        return;
    }

    $parent = $product->get_parent_id() ? $product->get_parent_id() : $product->get_id();
    $user   = wp_get_current_user();
    $log    = (array) get_post_meta( $parent, '_wpide_stock_log', true );

    array_unshift( $log, array(
        'time' => time(),
        'id'   => $product->get_id(),
        'qty'  => wc_stock_amount( $product->get_stock_quantity() ),
        'by'   => $user->exists() ? $user->display_name : ( wp_doing_cron() ? 'Scheduled task' : 'System / order' ),
    ) );

    update_post_meta( $parent, '_wpide_stock_log', array_slice( array_filter( $log ), 0, $wpide_stock_log_size ) );
};

add_action( 'woocommerce_product_set_stock', $wpide_stock_log );
add_action( 'woocommerce_variation_set_stock', $wpide_stock_log );

add_action( 'add_meta_boxes_product', function () {
    add_meta_box( 'wpide-stock-log', 'Stock history', function ( $post ) {
        $log = array_filter( (array) get_post_meta( $post->ID, '_wpide_stock_log', true ) );

        if ( ! $log ) {
            echo '<p>' . esc_html( 'No stock changes recorded yet.' ) . '</p>';
            return;
        }

        echo '<table class="widefat striped"><thead><tr><th>' . esc_html( 'Date' ) . '</th><th>' . esc_html( 'Item' ) . '</th><th>' . esc_html( 'Stock' ) . '</th><th>' . esc_html( 'By' ) . '</th></tr></thead><tbody>';

        foreach ( $log as $row ) {
            printf(
                '<tr><td>%1$s</td><td>%2$s</td><td>%3$s</td><td>%4$s</td></tr>',
                esc_html( wp_date( 'Y-m-d H:i', $row['time'] ) ),
                esc_html( (int) $row['id'] === (int) $post->ID ? '–' : get_the_title( $row['id'] ) ),
                esc_html( $row['qty'] ),
                esc_html( $row['by'] )
            );
        }

        echo '</tbody></table>';
    }, 'product', 'side', 'low' );
} );
```

## Notes

Only products that manage stock are logged, and variation changes are listed on their parent product.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Stock Change History on 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/
