Tùy biến giá cho sản phẩm trong Woocommerce

Hiển thị (sale flash) % chiết khấu cho sản phẩm – WooCommerce
8 December, 2016
Doanh Nghiệp Việt chậm chân với marketing hiện đại
9 December, 2016

Tùy biến giá cho sản phẩm trong Woocommerce

WooCommerce có 2 loại giá RegularSale, bạn có thể phân loại giá bán cho khách hàng quen thuộc đã đăng ký tài khoản trên website. Và bạn muốn thêm một giá đặc biệt cho loại khách hàng cụ thể có đăng nhập vào trang web bán hàng của bạn.

Sử dụng một vài đoạn code php, chúng ta sẽ thêm price mới đi kèm với regalar & sale price, giá này mình tạm gọi là Wholesale Price. Và chỉ hiển thị giá này cho người dùng đặc biệt với user role chỉ định.
Tạo hàm kiểm tra điều kiện user trên website có thể xem được Wholesale price. Để cho tiện, trong bài viết này mình chèn code vào theme functions.php. Hoặc các bạn có thể tạo plugin mới dành cho tính năng wholesale price.

// this checks if the current user is capable to have the wholesale pricing
function w4dev_wholesale_applicable(){
    return (bool) ( current_user_can('editor') && ( !is_admin() || is_ajax() ) );
}

Như vậy các tài khoản người dùng sử dụng trên web của tôi, có quyền editor sẽ mua được với giá Wholesale.
Giá của sản phẩm hiển thị ở mọi trang đều thông qua filter woocommerce_get_price, như vậy chúng ta cần tùy biến hàm liên kết với filter này để thay đổi lại giá với các user khác nhau gồm anonymous.
Thêm hàm hiển thị giá cho kiểu sản phẩm simplevariation.

// this get the wholesale price when available for both Simple & Variable product type
function w4dev_get_wholesale_price( $product )
{
    if( 
        $product->is_type( array('simple', 'variable') ) 
        && get_post_meta( $product->id, '_wholesale_price', true ) > 0 
    ){
        return get_post_meta( $product->id, '_wholesale_price', true );
    }
    elseif( 
        $product->is_type('variation') 
        && get_post_meta( $product->variation_id, '_wholesale_price', true ) > 0 
    ){
        return get_post_meta( $product->variation_id, '_wholesale_price', true );
    }
    return 0;
}

Để lấy mọi meta fields của product, chúng ta có hàm get_post_meta. Tên trường cho regular price, sale price là: _regular_price, _sale_price và trường wholesale mới thêm ở đây có ID “_wholesale_price”.

Các meta fields/custom fields của custom post type thường được viết dấu ‘_’ ở trước field name, để phân biệt với các fields mặc định của post type.

Ví dụ: hàm sau trả về giá regular price của sản phẩm hiện tại.

$price = get_post_meta( get_the_ID(), '_regular_price',true);
$sale = get_post_meta( get_the_ID(), '_sale_price', true);

Ngoài ra bạn có thể sử dụng WC_Product class trong woocommerce, và có thể trích xuất dữ liệu của mọi product. Nên kiểm tra class có tồn tại trước khi sử dụng, nếu WooCommerce chưa cài đặt.

if(class_exists('WC_Product')){
$product = new WC_Product( get_the_ID() );
$price = $product->price;	//plain
$price_html = $product->get_price_html();	//html format
}

Sử dụng hàm w4dev_get_wholesale_price vào hook woocommerce_get_price, để trả về giá cho từng loại sản phẩm. Thêm hook filter woocommerce_get_price vào file functions.php với nội dung sau:

add_filter( 'woocommerce_get_price', 'w4dev_woocommerce_get_price', 10, 2);
function w4dev_woocommerce_get_price( $price, $product )
{
    if( w4dev_wholesale_applicable() && w4dev_get_wholesale_price($product) > 0 )
        $price = w4dev_get_wholesale_price($product);
    return $price;
}

Wholesale Price cho Simple Product

Thêm trường nhập giá wholesale vào trang chỉnh sửa sản phẩm. Bạn sử dụng code này:

add_action( 'woocommerce_product_options_pricing', 'w4dev_woocommerce_product_options_pricing' );
function w4dev_woocommerce_product_options_pricing()
{
    woocommerce_wp_text_input( array( 
        'id' => '_wholesale_price',
        'class' => 'wc_input_wholesale_price short',
        'label' => __( 'Wholesale Price', 'woocommerce' ) . ' ('.get_woocommerce_currency_symbol().')',
        'type' => 'text'
    ));
}

Hook woocommerce_product_options_pricing sẽ thêm input field vào sau trường Sale Price. Lưu ý: Chỉ kiểu sản phẩm simple bạn mới thấy thôi nhé.
woocommerce-wholesale-price-simple-product

Tiếp theo, chúng ta cần lưu giá trị field _wholesale_price, sau khi nhấn nút Publish/Update.

add_action( 'woocommerce_process_product_meta_simple', 'w4dev_woocommerce_process_product_meta_simple', 10, 1 );
function w4dev_woocommerce_process_product_meta_simple( $product_id )
{
    if( isset($_POST['_wholesale_price']) && $_POST['_wholesale_price'] > 0 )
        update_post_meta( $product_id, '_wholesale_price', $_POST['_wholesale_price'] );
}

Mọi meta fields cho product, bạn có thể sử lý dữ liệu của fields tại đây trước khi lưu vào cơ sở dữ liệu. Sử dụng hàm update_post_meta vào product xác định bởi $product_id.
Như vậy là xong, bạn kiểm tra xem wholesale price có hoạt động không bằng cách đăng nhập với mọi tài khoản có quyền “editor” và bạn sẽ thấy giá của sản phẩm lấy từ giá trị của field wholesale thay cho sale/regular price. Tuy nhiên anonymous và các users khác không cho phép tương tác vào website với quyền “editor” sẽ quay về giá sale/regular price.

Wholesale Price cho Variation Product

Ở phần trên, là tính năng wholesale price áp dụng cho simple product, với loại sản phẩm Variation Product cũng sẽ tương tự. Trước khi tiếp tục, bạn nên tìm hiểu về cách tạo và sử dụng variation product trong woocommerce nếu chưa biết Variation Product làm việc như thế nào?

Thêm input field

add_action( 'woocommerce_product_after_variable_attributes', 'w4dev_woocommerce_product_after_variable_attributes', 10, 3 );
function w4dev_woocommerce_product_after_variable_attributes( $loop, $variation_data, $variation ){ ?>
    <tr class="wholesale_price_row">
        <td>
            <div>
                <label><?php _e( 'Wholesale Price:', 'woocommerce' ); ?></label>
                    <input type="text" size="5" name="variable_wholesale_price[<?php echo $loop; ?>]" value="<?php if ( isset( $variation_data['_wholesale_price'][0] ) ) echo esc_attr( $variation_data['_wholesale_price'][0] ); ?>" step="1" min="0" />
            </div>
        </td>
    </tr><?php
}

Mỗi lần thêm variation, field mới trong hàm liên kết với hook woocommerce_product_after_variable_attributes được hiển thị thêm vào các trường của variation product.

Lưu meta fields cho variation

Lưu các giá wholesales cho các variation, bởi hook woocommerce_save_product_variation sử dụng trong vòng lặp tất cả các variations, để lưu giá trị trường variable_wholesale_price.

add_action( 'woocommerce_save_product_variation', 'w4dev_woocommerce_save_product_variation', 10, 2 );
function w4dev_woocommerce_save_product_variation($variation_id, $i)
{
    if( isset($_POST['variable_wholesale_price'][$i]) )
        update_post_meta( $variation_id, '_wholesale_price', $_POST['variable_wholesale_price'][$i]);
}

Hiển thị Wholesale price cho variation

Như mình có nói ở trên, hàm w4dev_woocommerce_get_price và filter woocommerce_get_price sử dụng cho cả simple product và variation product. Hiển thị giá cuối cùng quyết định …
Tất cả giá trị regular price của các variation products có chạy qua filter woocommerce_variation_price_html, và sale price thông qua filter woocommerce_variation_sale_price_html. Hiển thị giá của sản phẩm bởi regular price/sale price, do đó để sản phẩm hiển thị giá wholesale, chúng ta sẽ sửa lại 2 filters này.

add_filter( 'woocommerce_variation_price_html', 'w4dev_woocommerce_variation_prices_html', 10, 2);
add_filter( 'woocommerce_variation_sale_price_html', 'w4dev_woocommerce_variation_prices_html', 10, 2);
function w4dev_woocommerce_variation_prices_html( $price, $product )
{
    if( isset($product->product_custom_fields['_wholesale_price'][0]) ){
        $wholesale_price = $product->product_custom_fields['_wholesale_price'][0];
		
    }else
        $wholesale_price = '';

    if( w4dev_wholesale_applicable() && $wholesale_price > 0 ){
        return woocommerce_price( $wholesale_price );
	}

    return $price;
}

Hàm w4dev_woocommerce_variation_prices_html trên chuyển về wholesale price cho từng loại variation, khi người dùng chuyển qua lại giữa các variation product.

Nếu không, từng variation sẽ hiển thị regular/sale price.

Tuy nhiên một dòng sản phẩm sẽ không hiển thị hết giá những variation của nó, mà hiển thị từ giá thấp nhất đến cao nhất, thang giá của loại sản phẩm variation dạng đoạn này sinh ra bởi hook woocommerce_get_price.

Hiển thị Minimum và Maximum Prices cho các variation product

Hiển thị giá của sản phẩm bao gồm giá trị và đơn vị thanh toán (vd: 100 $), được lưu trong dữ liệu của sản phẩm với thuộc tính price_html, mình vừa có bài viết nói về cách sử dụng thuộc tính “price_html”. Nhấn vào đây để tìm hiểu.
Chuỗi hiển thị giá cuối cùng dạng HTML mà bạn thấy trên mỗi sản phẩm (simple product, variation product,…) được sử lý bởi hook woocommerce_get_price_html.

add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html',10,2);
function wpa83367_price_html( $price, $product ){
	return $price;
}

Thêm HTML cho price

Chúng ta cho thể thêm chuỗi/HTML xen kẽ giá bán (sale price) và giá thị trường (regular price). Sửa lại hàm liên kết vào filter woocommerce_get_price_html như sau.

add_filter( 'woocommerce_get_price_html', 'wpa83368_price_html',10,2);
function wpa83367_price_html( $price, $product ){
    return 'Was:' . str_replace( '<ins>', ' Now:<ins>', $price );
}

Kết quả:
Single product:
price_html
Loop product:

Minimum hoặc Maximum với regular/sale price cho variation product

Mặc định woocommerce tính mức giá trung bình từ [x-y] cho variable product. Nhưng nếu bạn muốn hiển thị một giá nào đó trong số các variation của sản phẩm thì làm thế nào? Filter woocommerce_get_price_html , có truyền tham số $product cho bạn biến nhiều hơn, với thông tin này bạn có thể biết được loại sản phẩm. Đối với variable product WooCommerce có class WC_Product_Variable, từ đó lấy thông tin giá của các variation, theo ý bạn. Ví dụ dưới đây, mình sẽ cho hiển thị giá cao nhất trong số những variation products.

add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html',10,2);
function wpa83367_price_html( $price, $product ){
if($product->product_type=='variable'){
	$p=new WC_Product_Variable($product->id);
	return $p->get_variation_regular_price('max');
}

Tham khảo tài liệu WC_Product_Variable API.
Bạn cũng có thể lấy max price của variable product bởi biến $product->max_variation_price;.

add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html',10,2);
function wpa83367_price_html( $price, $product ){
	if($product->product_type=='variable'){
		return $product->max_variation_price;
	}
	return $price;
}

Hiển thị Minimum hoặc Maximum với custom price cho variation product

Trường hợp thêm Wholesale price trong bài viết này, chúng sẽ xác định từng giá trị meta field “_wholesale_price” của variation product và lấy ra con số cao nhất.

add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html',10,2);
function wpa83367_price_html( $price, $product ){	//unused
if($product->product_type=='variable'){
	$p=new WC_Product_Variable($product->id);
	$max=0;
	foreach($p->get_available_variations( ) as $variable){
		$wholesale_price=get_post_meta($variable['variation_id'],'_wholesale_price',true);
		if($wholesale_price>$max) $max=$wholesale_price;
	}
	return woocommerce_price($max);
}

Đảm bảo giá hiển thị lên shop có đầy đủ cả đơn vị tiền tệ, bạn lấy giá trị trả về của hàm woocommerce_price. Save file lại, và kiểm tra lại tài khoản đăng nhập vào wordpress, sau khi load lại trang bạn sẽ nhìn thấy giá wholesale cao nhất được hiển thị.

Chúc bạn thành công.

Trả lời

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

five × 4 =