در ووکامرس به‌صورت پیش‌فرض امکان فعال‌کردن ارسال رایگان بر اساس تعداد یک محصول مشخص یا مجموعه‌ای از محصولات وجود ندارد. با استفاده از قطعه‌کدهای زیر می‌توانید تعیین کنید که وقتی مشتری حداقل ۲ عدد از محصولات موردنظر را به سبد خرید اضافه کرد، روش‌های ارسال پولی مخفی شوند و فقط گزینه «ارسال رایگان» نمایش داده شود.

این آموزش سه حالت مختلف را پوشش می‌دهد:

  1. یک محصول مشخص: با خرید حداقل ۲ عدد از یک محصول خاص، ارسال رایگان فعال می‌شود.
  2. چند محصول به‌صورت جداگانه: اگر تعداد یکی از محصولات منتخب به ۲ عدد برسد، ارسال رایگان فعال می‌شود.
  3. مجموع چند محصول منتخب: اگر مجموع تعداد محصولات منتخب به ۲ عدد برسد، حتی اگر محصولات متفاوت باشند، ارسال رایگان فعال می‌شود.

این کدها برای محصولات ساده و متغیر قابل استفاده‌اند. در محصولات متغیر باید شناسه محصول اصلی یا والد را وارد کنید؛ در این صورت تمام تنوع‌های آن محصول با هم محاسبه می‌شوند.

پیش‌نیاز اجرای کدها

قبل از استفاده از قطعه‌کدها، باید در منطقه حمل‌ونقل موردنظر ووکامرس یک روش «ارسال رایگان» ایجاد کنید:

ووکامرس ← پیکربندی ← حمل‌ونقل ← مناطق حمل‌ونقل ← افزودن روش حمل‌ونقل

سپس:

  • روش ارسال رایگان را اضافه کنید.
  • شرط آن را روی بدون نیازمندی قرار دهید.
  • کد مربوط به حالت دلخواه را در افزونه WPCode یا Code Snippets وارد کنید.
  • فقط یکی از سه قطعه‌کد را فعال نگه دارید تا با یکدیگر تداخل نداشته باشند.

در هر قطعه‌کد نیز باید شناسه‌های نمونه مانند 1234، 5678 و 9012 را با شناسه واقعی محصولات سایت خود جایگزین کنید.

نکته: اگر چند منطقه حمل‌ونقل تعریف کرده‌اید، روش ارسال رایگان باید در تمام منطقه‌هایی که قرار است این قابلیت در آن‌ها اجرا شود، اضافه شده باشد. همچنین پس از فعال‌کردن کد، کش سایت و سبد خرید را پاک کرده و عملکرد آن را در یک پنجره ناشناس آزمایش کنید.

حالت اول: رفتار زیر را ایجاد می‌کند:

  • کمتر از ۲ عدد محصول موردنظر: ارسال رایگان مخفی می‌شود.
  • ۲ عدد یا بیشتر: روش‌های پولی مخفی می‌شوند و فقط ارسال رایگان نمایش داده می‌شود.
  • تمام تنوع‌های محصول متغیر با هم شمرده می‌شوند.
  • وجود محصولات دیگر در سبد مانع ارسال رایگان نمی‌شود.
add_filter( 'woocommerce_package_rates', 'free_shipping_for_product_qty', 100, 2 );

function shipping_for_product_qty( $rates, $package ) {

    // شناسه محصول اصلی (والد) را وارد کنید؛ نه شناسه تنوع
    $target_product_id = 1234;

    // حداقل تعداد موردنیاز
    $required_qty = 2;

    $target_qty = 0;

    // شمارش تعداد محصول در همین بسته حمل‌ونقل
    if ( ! empty( $package['contents'] ) ) {
        foreach ( $package['contents'] as $cart_item ) {

            $product_id   = isset( $cart_item['product_id'] )
                ? (int) $cart_item['product_id']
                : 0;

            $variation_id = isset( $cart_item['variation_id'] )
                ? (int) $cart_item['variation_id']
                : 0;

            /*
             * برای محصولات متغیر، product_id معمولاً شناسه محصول والد است.
             * شرط variation_id نیز برای انعطاف بیشتر بررسی می‌شود.
             */
            if (
                $product_id === $target_product_id ||
                $variation_id === $target_product_id
            ) {
                $target_qty += (int) $cart_item['quantity'];
            }
        }
    }

    /*
     * اگر حداقل ۲ عدد وجود دارد:
     * فقط ارسال رایگان نمایش داده شود.
     */
    if ( $target_qty >= $required_qty ) {

        $free_rates = array();

        foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id ) {
                $free_rates[ $rate_id ] = $rate;
            }
        }

        // فقط در صورتی جایگزین می‌کنیم که روش ارسال رایگان موجود باشد
        if ( ! empty( $free_rates ) ) {
            return $free_rates;
        }

        return $rates;
    }

    /*
     * اگر تعداد کمتر از ۲ است:
     * ارسال رایگان حذف شود و روش‌های پولی باقی بمانند.
     */
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            unset( $rates[ $rate_id ] );
        }
    }

    return $rates;
}

فقط این قسمت را تغییر بده:

$target_product_id = 1234;

و به‌جای 1234، شناسه محصول اصلی/والد را وارد کن.

حالت دوم: حداقل ۲ عدد از یکی از محصولات منتخب

در این حالت، اگر کاربر از هرکدام از محصولات مشخص‌شده ۲ عدد یا بیشتر خرید کند، ارسال رایگان می‌شود.

  • ۲ عدد محصول A → رایگان
  • ۲ عدد محصول B → رایگان
  • ۱ عدد A + ۱ عدد B → غیررایگان
  • ۲ عدد A + هر تعداد محصول دیگر → رایگان
add_filter( 'woocommerce_package_rates', 'free_shipping_for_selected_products', 100, 2 );

function free_shipping_for_selected_products( $rates, $package ) {

    /*
     * شناسه محصولات اصلی/والد را وارد کنید.
     * برای محصولات متغیر، شناسه محصول والد را قرار دهید، نه شناسه تنوع.
     */
    $target_product_ids = array(
        1234,
        5678,
        9012,
    );

    // حداقل تعداد از یکی از محصولات منتخب
    $required_qty = 2;

    // نگهداری تعداد هر محصول به‌صورت جداگانه
    $product_quantities = array();

    foreach ( $target_product_ids as $product_id ) {
        $product_quantities[ $product_id ] = 0;
    }

    // شمارش تعداد هر محصول منتخب در بسته حمل‌ونقل
    if ( ! empty( $package['contents'] ) ) {

        foreach ( $package['contents'] as $cart_item ) {

            $product_id = isset( $cart_item['product_id'] )
                ? (int) $cart_item['product_id']
                : 0;

            $quantity = isset( $cart_item['quantity'] )
                ? (int) $cart_item['quantity']
                : 0;

            /*
             * در محصول متغیر، product_id شناسه محصول والد است.
             */
            if ( in_array( $product_id, $target_product_ids, true ) ) {
                $product_quantities[ $product_id ] += $quantity;
            }
        }
    }

    $free_shipping_allowed = false;

    // بررسی می‌کند آیا حداقل یکی از محصولات به تعداد موردنیاز رسیده است
    foreach ( $product_quantities as $quantity ) {
        if ( $quantity >= $required_qty ) {
            $free_shipping_allowed = true;
            break;
        }
    }

    /*
     * در صورت برقرار بودن شرط، فقط روش ارسال رایگان نمایش داده شود.
     */
    if ( $free_shipping_allowed ) {

        $free_rates = array();

        foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id ) {
                $free_rates[ $rate_id ] = $rate;
            }
        }

        if ( ! empty( $free_rates ) ) {
            return $free_rates;
        }

        return $rates;
    }

    /*
     * در صورت برقرار نبودن شرط، ارسال رایگان مخفی شود.
     */
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            unset( $rates[ $rate_id ] );
        }
    }

    return $rates;
}

فقط شناسه‌ها را در این قسمت وارد کن:

$target_product_ids = array(
    1234,
    5678,
    9012,
);

حالت سوم: مجموع محصولات منتخب حداقل ۲ عدد باشد

اگر می‌خواهی ترکیب محصولات هم محاسبه شود، از این نسخه استفاده کن.

  • ۲ عدد محصول A → رایگان
  • ۲ عدد محصول B → رایگان
  • ۱ عدد A + ۱ عدد B → رایگان
  • ۱ عدد A + یک محصول غیرمنتخب → غیررایگان
add_filter( 'woocommerce_package_rates', 'free_shipping_for_selected_products_total_qty', 100, 2 );

function free_shipping_for_selected_products_total_qty( $rates, $package ) {

    /*
     * شناسه محصولات اصلی/والد
     */
    $target_product_ids = array(
        1234,
        5678,
        9012,
    );

    // حداقل مجموع تعداد محصولات منتخب
    $required_qty = 2;

    $total_target_qty = 0;

    if ( ! empty( $package['contents'] ) ) {

        foreach ( $package['contents'] as $cart_item ) {

            $product_id = isset( $cart_item['product_id'] )
                ? (int) $cart_item['product_id']
                : 0;

            $quantity = isset( $cart_item['quantity'] )
                ? (int) $cart_item['quantity']
                : 0;

            /*
             * تمام تنوع‌های محصول بر اساس شناسه والد محاسبه می‌شوند.
             */
            if ( in_array( $product_id, $target_product_ids, true ) ) {
                $total_target_qty += $quantity;
            }
        }
    }

    /*
     * اگر مجموع محصولات منتخب حداقل ۲ عدد باشد،
     * فقط ارسال رایگان نمایش داده شود.
     */
    if ( $total_target_qty >= $required_qty ) {

        $free_rates = array();

        foreach ( $rates as $rate_id => $rate ) {
            if ( 'free_shipping' === $rate->method_id ) {
                $free_rates[ $rate_id ] = $rate;
            }
        }

        if ( ! empty( $free_rates ) ) {
            return $free_rates;
        }

        return $rates;
    }

    /*
     * اگر شرط برقرار نیست، ارسال رایگان مخفی شود.
     */
    foreach ( $rates as $rate_id => $rate ) {
        if ( 'free_shipping' === $rate->method_id ) {
            unset( $rates[ $rate_id ] );
        }
    }

    return $rates;
}

فقط شناسه‌ها را در این قسمت وارد کن:

$target_product_ids = array(
    1234,
    5678,
    9012,
);