Change Stock By Product Tag

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #123812
    Julian Stysis
    Participant

    Hello,

    Is it possible to enhance the product to only change stock of products with a specific product tag?

    I’m renting and selling products on my site and when customers have a mixed order with both rental and purchased products, I need to reset stock of only the rental products when they’re returned. The way the plugin works now, is is that it resets stock for all products in a given order, which in my case includes purchased products and that’s not the desired outcome.

    I’d like to be able to configure the plugin to only change stock of products with a given tag and ignore others.

    Thank you

    #123861
    Moshtafizur
    Moderator
    Plugin Support

    Hi Julian,

    Thanks for reaching out.

    At this moment, it is not possible to update stock only for products with a specific tag only. But I have passed your request to our development team. They will get back to you as soon as possible.

    Kind regards,
    Moshtafizur

    #123905
    Julian Stysis
    Participant

    Thank you for the quick response. May be this enhancement request could be expedited for a small fee?

    #124788
    Tom Anbinder
    Moderator
    Plugin Support

    Hi, Julian,

    Haven’t we solved it with you with this snippet?

    /**
     * alg_wc_stock_triggers_function_increase.
     */
    add_filter( 'alg_wc_stock_triggers_function_increase', function () {
        return 'my_wc_maybe_increase_stock_levels';
    } );
    
    /**
     * my_wc_maybe_increase_stock_levels.
     *
     * @see https://github.com/woocommerce/woocommerce/blob/7.7.0/plugins/woocommerce/includes/wc-stock-functions.php#L123
     */
    if ( ! function_exists( 'my_wc_maybe_increase_stock_levels' ) ) {
        function my_wc_maybe_increase_stock_levels( $order_id ) {
            $order = wc_get_order( $order_id );
    
            if ( ! $order ) {
                return;
            }
    
            $stock_reduced    = $order->get_data_store()->get_stock_reduced( $order_id );
            $trigger_increase = (bool) $stock_reduced;
    
            // Only continue if we're increasing stock.
            if ( ! $trigger_increase ) {
                return;
            }
    
            my_wc_increase_stock_levels( $order );
    
            // Ensure stock is not marked as "reduced" anymore.
            $order->get_data_store()->set_stock_reduced( $order_id, false );
        }
    }
    
    /**
     * my_wc_increase_stock_levels.
     *
     * @see https://github.com/woocommerce/woocommerce/blob/7.7.0/plugins/woocommerce/includes/wc-stock-functions.php#L268
     */
    if ( ! function_exists( 'my_wc_increase_stock_levels' ) ) {
        function my_wc_increase_stock_levels( $order_id ) {
            if ( is_a( $order_id, 'WC_Order' ) ) {
                $order    = $order_id;
                $order_id = $order->get_id();
            } else {
                $order = wc_get_order( $order_id );
            }
    
            // We need an order, and a store with stock management to continue.
            if ( ! $order || 'yes' !== get_option( 'woocommerce_manage_stock' ) || ! apply_filters( 'woocommerce_can_restore_order_stock', true, $order ) ) {
                return;
            }
    
            $changes = array();
    
            // Loop over all items.
            foreach ( $order->get_items() as $item ) {
                if ( ! $item->is_type( 'line_item' ) ) {
                    continue;
                }
    
                // Only increase stock once for each item.
                $product            = $item->get_product();
                $item_stock_reduced = $item->get_meta( '_reduced_stock', true );
    
                if ( ! $item_stock_reduced || ! $product || ! $product->managing_stock() ) {
                    continue;
                }
    
                // Check order status and product tag
                $check_order_status     = array( 'your-order-status' );
                $check_product_tag_slug = 'your-product-tag';
                if ( $order->has_status( $check_order_status ) ) {
                    $tags = wc_get_product_terms( ( $product->get_parent_id() ? $product->get_parent_id() : $product->get_id() ), 'product_tag' );
                    $tags = wp_list_pluck( $tags, 'slug' );
                    if ( in_array( $check_product_tag_slug, $tags ) ) {
                        continue;
                    }
                }
    
                $item_name = $product->get_formatted_name();
                $new_stock = wc_update_product_stock( $product, $item_stock_reduced, 'increase' );
    
                if ( is_wp_error( $new_stock ) ) {
                    /* translators: %s item name. */
                    $order->add_order_note( sprintf( __( 'Unable to restore stock for item %s.', 'woocommerce' ), $item_name ) );
                    continue;
                }
    
                $item->delete_meta_data( '_reduced_stock' );
                $item->save();
    
                $changes[] = $item_name . ' ' . ( $new_stock - $item_stock_reduced ) . '→' . $new_stock;
            }
    
            if ( $changes ) {
                $order->add_order_note( __( 'Stock levels increased:', 'woocommerce' ) . ' ' . implode( ', ', $changes ) );
            }
    
            do_action( 'woocommerce_restore_order_stock', $order );
        }
    }
    

    The code is not very small, but 99% of it is a copy of these two standard WooCommerce functions:
    https://github.com/woocommerce/woocommerce/blob/7.7.0/plugins/woocommerce/includes/wc-stock-functions.php#L123
    https://github.com/woocommerce/woocommerce/blob/7.7.0/plugins/woocommerce/includes/wc-stock-functions.php#L268

    You need to modify only these two lines in the snippet:

    $check_order_status     = array( 'your-order-status' );
    $check_product_tag_slug = 'your-product-tag';
    

    That is, now the snippet will not increase stock on order status change to your-order-status for the products with the your-product-tag tag – you need to set your order status and product tag here.

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.