简体   繁体   中英

Prevent adjust line item stock for custom stock quantity reduction in WooCommerce

Like many other users when followed this tutorial , I ran into the following problem

If I change the status of the order afterwards to completed then this happen, the custom stock is added back with the difference between the adjusted number and the original number.

How can I prevent this?

ps I contacted the tutorial writer several times for this months ago, unfortunately without any response

Code from the tutorial

/**
 * Simple product setting.
 */
function ace_add_stock_inventory_multiplier_setting() {

    ?><div class='options_group'><?php

        woocommerce_wp_text_input( array(
            'id'                => '_stock_multiplier',
            'label'             => __( 'Inventory reduction per quantity sold', 'woocommerce' ),
            'desc_tip'          => 'true',
            'description'       => __( 'Enter the quantity multiplier used for reducing stock levels when purchased.', 'woocommerce' ),
            'type'              => 'number',
            'custom_attributes' => array(
                'min'   => '1',
                'step'  => '1',
            ),
        ) );

    ?></div><?php

}
add_action( 'woocommerce_product_options_inventory_product_data', 'ace_add_stock_inventory_multiplier_setting' );

/**
 * Add variable setting.
 *
 * @param $loop
 * @param $variation_data
 * @param $variation
 */
function ace_add_variation_stock_inventory_multiplier_setting( $loop, $variation_data, $variation ) {

    $variation = wc_get_product( $variation );
    woocommerce_wp_text_input( array(
        'id'                => "stock_multiplier{$loop}",
        'name'              => "stock_multiplier[{$loop}]",
        'value'             => $variation->get_meta( '_stock_multiplier' ),
        'label'             => __( 'Inventory reduction per quantity sold', 'woocommerce' ),
        'desc_tip'          => 'true',
        'description'       => __( 'Enter the quantity multiplier used for reducing stock levels when purchased.', 'woocommerce' ),
        'type'              => 'number',
        'custom_attributes' => array(
            'min'   => '1',
            'step'  => '1',
        ),
    ) );

}
add_action( 'woocommerce_variation_options_pricing', 'ace_add_variation_stock_inventory_multiplier_setting', 50, 3 );

/**
 * Save the custom fields.
 *
 * @param WC_Product $product
 */
function ace_save_custom_stock_reduction_setting( $product ) {

    if ( ! empty( $_POST['_stock_multiplier'] ) ) {
        $product->update_meta_data( '_stock_multiplier', absint( $_POST['_stock_multiplier'] ) );
    }
}
add_action( 'woocommerce_admin_process_product_object', 'ace_save_custom_stock_reduction_setting'  );

/**
 * Save custom variable fields.
 *
 * @param int $variation_id
 * @param $i
 */
function ace_save_variable_custom_stock_reduction_setting( $variation_id, $i ) {
    $variation = wc_get_product( $variation_id );
    if ( ! empty( $_POST['stock_multiplier'] ) && ! empty( $_POST['stock_multiplier'][ $i ] ) ) {
        $variation->update_meta_data( '_stock_multiplier', absint( $_POST['stock_multiplier'][ $i ] ) );
        $variation->save();
    }
}
add_action( 'woocommerce_save_product_variation', 'ace_save_variable_custom_stock_reduction_setting', 10, 2 );

/**
 * Reduce with custom stock quantity based on the settings.
 *
 * @param $quantity
 * @param $order
 * @param $item
 * @return mixed
 */
function ace_custom_stock_reduction( $quantity, $order, $item ) {

    /** @var WC_Order_Item_Product $product */
    $multiplier = $item->get_product()->get_meta( '_stock_multiplier' );

    if ( empty( $multiplier ) && $item->get_product()->is_type( 'variation' ) ) {
        $product = wc_get_product( $item->get_product()->get_parent_id() );
        $multiplier = $product->get_meta( '_stock_multiplier' );
    }

    if ( ! empty( $multiplier ) ) {
        $quantity = $multiplier * $quantity;
    }

    return $quantity;
}
add_filter( 'woocommerce_order_item_quantity', 'ace_custom_stock_reduction', 10, 3 );

What I first tried, unfortunately a dirty solution, without the desired result

/**
 * Reduce with custom stock quantity based on the settings.
 *
 * @param $quantity
 * @param $order
 * @param $item
 * @return $quantity
 */
function dvpi_custom_stock_reduction( $quantity, $order, $item ) {
    /** @var WC_Order_Item_Product $product */

    $multiplier = $item->get_product()->get_meta( '_stock_multiplier' );

    if ( ! empty( $multiplier ) ) {
        // Get product (parent) id
        $product_id = $item->get_product_id();

        // Get product object
        $product = wc_get_product( $product_id );

        // Get product stock
        $product_stock = $product->get_stock_quantity();

        // Calculate the reduce
        $reduce = $multiplier * $quantity;

        // Update stock
        wc_update_product_stock( $product, $product_stock - $reduce );

        // 0 because we do not use the standard behavior
        $quantity = 0;
    }

    return $quantity;
}
add_filter( 'woocommerce_order_item_quantity', 'dvpi_custom_stock_reduction', 10, 3 );

The solution is to add an extra hook, namely woocommerce_prevent_adjust_line_item_product_stock .

In this way, we check whether the condition of the $multiplier is met and we prevent it from being adjusted.

/**
 * Prevent adjust line item
 * 
 * @param $prevent
 * @param $item
 * @param $quantity
 */
function prevent_adjust_line_item ( $prevent, $item, $quantity ) {
    // Get multiplier
    $multiplier = $item->get_product()->get_meta( '_stock_multiplier' );

    // Empty & product is type variation
    if ( empty( $multiplier ) && $item->get_product()->is_type( 'variation' ) ) {
        $product = wc_get_product( $item->get_product()->get_parent_id() );
        $multiplier = $product->get_meta( '_stock_multiplier' );
    }

    // NOT empty
    if ( ! empty( $multiplier ) ) {
        $prevent = true;
    }

    return $prevent;
}
add_filter( 'woocommerce_prevent_adjust_line_item_product_stock', 'prevent_adjust_line_item', 10, 3 );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM