• A year ago I wanted to set up a shop that sells a product by weight (kg). So after you create variations, e.g. 2kg pack, 5kg pack, etc., it is displayed correctly in the frontend, but the problem is that after the order only 1 unit is removed from the stock. That’s why I wanted a simple multiplier so that you can interpret the stock as a unit.

    Example: Apples
    Stock is 100 (kg)
    Variation: 2kg Apples, 5kg Apples, 10kg Apples
    For each variation you set the multiplier accordingly: 2 for 2kg, 5 for 5kg, etc.

    more: https://ww.wp.xz.cn/support/topic/manage-stock-by-weight/

    All the plugins I found cost at least €3 to €7 per month. Don’t be mad at me, but I don’t see any reason to pay more monthly for such a simple function than my entire hosting costs!

    Disclaimer. I am NOT an expert and have no programming knowledge. This plugin was written entirely by AI (Grok3) and I take NO liability or responsibility in any way! Use at your own risk.

    However, it works great for me and that’s why I want to share it with you.

    I don’t know how to upload a .zip file here, so here’s the code:
    Name the file woocommerce-stock-multiplier.php and place it in the folder wp-content/plugins/woocommerce-stock-multiplier

    <?php
    /*
    * Plugin Name: WooCommerce Stock Multiplier
    * Description: Adjusts stock deduction based on a multiplier per variation and prevents orders if stock would go negative.
    * Version: 1.1
    * Author: .:shIxx:.
    */

    // Ensure WooCommerce is active
    if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {

    // Add multiplier field to variation options in the backend
    add_action('woocommerce_variation_options_pricing', 'add_multiplier_field_to_variations', 10, 3);
    function add_multiplier_field_to_variations($loop, $variation_data, $variation) {
    woocommerce_wp_text_input(array(
    'id' => 'multiplier_' . $variation->ID,
    'label' => __('Stock Multiplier', 'woocommerce'),
    'description' => __('Enter the multiplier for stock deduction (e.g., 3 for 3 units per item).', 'woocommerce'),
    'value' => get_post_meta($variation->ID, '_multiplier', true),
    'type' => 'number',
    'desc_tip' => true,
    'custom_attributes' => array(
    'step' => '0.1',
    'min' => '0'
    )
    ));
    }

    // Save the multiplier value
    add_action('woocommerce_save_product_variation', 'save_multiplier_field_variations', 10, 2);
    function save_multiplier_field_variations($variation_id, $i) {
    $multiplier = isset($_POST['multiplier_' . $variation_id]) ? wc_clean($_POST['multiplier_' . $variation_id]) : '';
    update_post_meta($variation_id, '_multiplier', $multiplier);
    }

    // Validate stock before adding to cart or checkout
    add_filter('woocommerce_add_to_cart_validation', 'validate_stock_before_cart', 10, 5);
    function validate_stock_before_cart($passed, $product_id, $quantity, $variation_id = 0, $variations = array()) {
    if ($variation_id > 0) {
    $multiplier = floatval(get_post_meta($variation_id, '_multiplier', true));
    if ($multiplier > 0) {
    $parent_product = wc_get_product($product_id);
    $current_stock = $parent_product->get_stock_quantity();

    // Calculate total stock reduction
    $stock_reduction = $quantity * $multiplier;

    // Check if stock would go negative
    if ($current_stock - $stock_reduction < 0) {
    wc_add_notice(__('Sorry, there is not enough stock available for this item.', 'woocommerce'), 'error');
    return false; // Prevent adding to cart
    }
    }
    }
    return $passed;
    }

    // Validate stock again at checkout
    add_action('woocommerce_check_cart_items', 'validate_stock_at_checkout');
    function validate_stock_at_checkout() {
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
    $product = $cart_item['data'];
    $quantity = $cart_item['quantity'];

    if ($product->is_type('variation')) {
    $variation_id = $cart_item['variation_id'];
    $multiplier = floatval(get_post_meta($variation_id, '_multiplier', true));

    if ($multiplier > 0) {
    $parent_product = wc_get_product($product->get_parent_id());
    $current_stock = $parent_product->get_stock_quantity();

    // Calculate total stock reduction
    $stock_reduction = $quantity * $multiplier;

    // Check if stock would go negative
    if ($current_stock - $stock_reduction < 0) {
    wc_add_notice(__('Sorry, there is not enough stock available for one or more items in your cart.', 'woocommerce'), 'error');
    return; // This will block checkout
    }
    }
    }
    }
    }

    // Prevent WooCommerce default stock reduction for variations with multiplier
    add_filter('woocommerce_order_item_quantity', 'prevent_default_stock_reduction', 10, 3);
    function prevent_default_stock_reduction($quantity, $order, $item) {
    $product = $item->get_product();
    if ($product->is_type('variation')) {
    $variation_id = $item->get_variation_id();
    $multiplier = floatval(get_post_meta($variation_id, '_multiplier', true));
    if ($multiplier > 0) {
    return 0; // Set default reduction to 0, we'll handle it ourselves
    }
    }
    return $quantity; // Default behavior for non-multiplier items
    }

    // Adjust stock based on multiplier when order is processed
    add_action('woocommerce_order_status_processing', 'adjust_stock_based_on_multiplier');
    function adjust_stock_based_on_multiplier($order_id) {
    $order = wc_get_order($order_id);

    foreach ($order->get_items() as $item_id => $item) {
    $product = $item->get_product();
    $quantity = $item->get_quantity(); // Quantity ordered (e.g., 2)

    // Check if it's a variation
    if ($product->is_type('variation')) {
    $variation_id = $item->get_variation_id();
    $multiplier = floatval(get_post_meta($variation_id, '_multiplier', true)); // Multiplier (e.g., 5)

    if ($multiplier > 0) {
    $parent_product = wc_get_product($product->get_parent_id());
    $current_stock = $parent_product->get_stock_quantity(); // Current stock (e.g., 100)

    // Calculate stock reduction: Quantity * Multiplier
    $stock_reduction = $quantity * $multiplier; // e.g., 2 * 5 = 10

    // Update stock
    $new_stock = $current_stock - $stock_reduction;
    wc_update_product_stock($parent_product, $new_stock);
    }
    }
    }
    }
    }

The topic ‘Manage WooCommerce stock by units’ is closed to new replies.