WordPressのWelcartで商品ごとに割引額を設定する方法

WordPressのプラグイン「Welcart」に関する記事です。

デフォルトでは全ての商品に同じ割引額が適応されます。
以下は、商品ごとに割引額を設定する方法です。

<h2>各商品に割引額の入力欄をつける</h2>

カスタムフィールドを追加して、割引額を設定できるようにします。

```php:function.php
// カスタムフィールドの追加
add_action( 'admin_menu', 'add_custom_field' );
function add_custom_field() {
    add_meta_box( 'custom-discount', '商品個別の割引率', 'create_discount', 'post', 'normal' );
}
// カスタムフィールドのHTML
function create_discount() {
    global $post;
    $keyname = 'item_discount';
    // 保存されているカスタムフィールドの値を取得
    $get_value = get_post_meta( $post->ID, $keyname, true );
    // nonceの追加
    wp_nonce_field( 'action-' . $keyname, 'nonce-' . $keyname );
    // HTMLの出力
    echo '<input name="' . $keyname . '" value="' . $get_value . '">';
}
// カスタムフィールドの保存
add_action( 'save_post', 'save_custom_field' );
    function save_custom_field( $post_id ) {
        $custom_fields = ['item_discount'];
        foreach( $custom_fields as $d ) {
            if ( isset( $_POST['nonce-' . $d] ) && $_POST['nonce-' . $d] ) {
                if( check_admin_referer( 'action-' . $d, 'nonce-' . $d ) ) {
                    if( isset( $_POST[$d] ) && $_POST[$d] ) {
                        update_post_meta( $post_id, $d, $_POST[$d] );
                    } else {
                        delete_post_meta( $post_id, $d, get_post_meta( $post_id, $d, true ) );
                    }
                }
            }
        }
    }
}
```


<h2>各商品ページに割引額を表示する。</h2>

商品ページに表示している価格に、割引額を追加します。

商品ページに該当するphpファイル内の、価格表示部分を以下のように修正します。

```php
//セール対象のカテゴリかどうか
$is_sale = false;
$salecat = $usces->options['campaign_category'];
$cats = get_the_category();
foreach($cats as $cat){
    if($cat->term_id == $salecat){
        $is_sale = true;
        break;
    }
}
$fields = $usces->itemskus;
foreach( $fields as $key => $field){
    $display = $key == 0 ? "inline-block" : "none";
    $price = $field['price'];
    $discount_p = get_post_meta(get_the_ID(), 'item_discount', true);
    if( ! $is_sale){
        //セール対象ではない商品
        echo "<span class='product-price sku{$key}' style='display:{$display};'>¥".number_format($price)."（税込）</span>";
    }else{
        if($discount_p != '' && $discount_p > 0){
            //セール対象かつ、商品個別の割引率が設定されている場合
            $price2 = $price * (100 - $discount_p) * 0.01;
            echo "<span class='product-price sku{$key}' style='display:{$display};'>
                    
¥".number_format($price)."（税込）

                    <br><span style='color:#f33;'>
                    ¥".number_format($price2)."（税込）".((1-$price2/$price)*100)."%OFF</span>
                </span>";
        }else{
            //セール対象かつ、商品個別の割引率が設定されていない場合（全体の割引率を設定）
            $sale_type = $usces->options['campaign_privilege'];
            $sale_discount = $usces->options['privilege_discount'];
            if($sale_type == 'discount' && $sale_discount != '' && $sale_discount > 0 ){
                $price2 = $price * (100 - $sale_discount) * 0.01;
                echo "<span class='product-price sku{$key}' style='display:{$display};'>
                        
¥".number_format($price)."（税込）

                        <br><span style='color:#f33;'>
                        ¥".number_format($price2)."（税込）".((1-$price2/$price)*100)."%OFF</span>
                    </span>";
            }else{
                echo "<span class='product-price sku{$key}' style='display:{$display};'>
                        ¥".number_format($price)."（税込）
                    </span>";
            }
        }
    }
}
```

<h2>カートにおける割引額の計算を修正する。</h2>

カートに商品を入れたときの割引表示を修正します。

以下のコードを function.php に追加します。

```php:function.php
//商品別の値引き
add_filter('usces_order_discount', 'product_order_discount', 10, 2);
function product_order_discount($discount, $cart){
    global $usces;
    //セール情報の取得
    $salecat = $usces->options['campaign_category'];
    $sale_type = $usces->options['campaign_privilege'];
    $sale_discount = $usces->options['privilege_discount'];
    $discount = 0;
    foreach($cart as $product){
	$postid = $product['post_id'];
	$post_categories = wp_get_post_categories( $postid );
	//セール対象の商品のみ適用
	if(array_search($salecat, $post_categories) !== false){
	    $discount_p = get_post_meta($postid, 'item_discount', true);
	    if($discount_p != ''){
                $discount += $product['price'] * $product['quantity'] * $discount_p * -0.01;
	    }else{
		if($sale_type == 'discount'){
	    	    $discount += $product['price'] * $product['quantity'] * $sale_discount * -0.01;
		}
	    }
	}
    }
    return $discount;
}
```

<h2>【補足】個別の割引額から送料無料条件を更新する。</h2>

送料無料条件を使用している場合は、
割引後の価格を条件に適用させます。

```php:function.php
//送料を割引後の価格に適応
add_filter( 'usces_filter_set_cart_fees_shipping_charge', 'my_filter_set_cart_fees_shipping_charge', 10, 3);
function my_filter_set_cart_fees_shipping_charge($shipping_charge, $carts, $entries){
    global $usces;
    //discount更新
    $salecat = $usces->options['campaign_category'];
    $sale_type = $usces->options['campaign_privilege'];
    $sale_discount = $usces->options['privilege_discount'];
    $entries['order']['discount'] = 0;
    foreach($carts as $product){
	$postid = $product['post_id'];
	$post_categories = wp_get_post_categories( $postid );
	if(array_search($salecat, $post_categories) !== false){
	    $discount_p = get_post_meta($postid, 'item_discount', true);
	    if($discount_p != ''){
		$discount += $product['price'] * $product['quantity'] * $discount_p * -0.01;
	    }else{
		if($sale_type == 'discount'){
		    $discount += $product['price'] * $product['quantity'] * $sale_discount * -0.01;
		}
	    }
	}
    }
    $entries['order']['discount'] += $discount;
    $entries['order']['total_price'] = intval($entries['order']['total_items_price']) + intval($entries['order']['discount']);
    $entries['order']['total_full_price'] = $entries['order']['total_price'];
    //送料再取得
    $shipping_charge = $usces->options['shipping_charge'][0]['JP'][$entries['customer']['pref']];
    //送料無料条件
    $free_border_price = intval(preg_replace('/[^0-9]/', '', $usces->sc_postage_privilege()));
    if ($entries['order']['total_price'] >= $free_border_price) {
    	$shipping_charge = 0;
    }
    return $shipping_charge;
}
```