EC-CUBEのもともとの送料個別設定だと、設定された送料を、商品数分すべてプラスされるという仕組みになってるので、
例えば送料500円の商品を2つ買うと、送料1000円になってしまいます。
しかも一律の送料などを設定してる場合はさらにその送料もプラスされてしまいますので、
おそらく困ったことになります。

なので、今回は簡単に個別に商品に送料無料を設けれ、
さらに上記の困った仕組みを使いやすくする方法をメモ

※ホントはデータベースに新しく項目を追加して出来ればよかったのですがよくわからなかったので、
今回は元からあるOPTION_PRODUCT_DELIV_FEEというパラメータを使ってします。

OPTION_PRODUCT_DELIV_FEEの設定

おそらくデフォルトではOPTION_PRODUCT_DELIV_FEEは
商品の編集部分
このように無効になっていると思うので、
管理画面のパラメータ設定から
OPTION_PRODUCT_DELIV_FEEを有効にします。
有効にしたら「※現在無効です」という
表記がなくなるので確認してください。

SC_Cartsession.phpの編集

あとは
data/class/SC_Cartsession.php

// 商品ごとの送料を加算
if (OPTION_PRODUCT_DELIV_FEE == 1) {
    $cartItems = $this->getCartList($productTypeId);
    foreach ($cartItems as $item) {
$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
    }
}

// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1
    && !SC_Utils_Ex::isBlank($deliv_pref)
    && !SC_Utils_Ex::isBlank($deliv_id)) {
    $results['deliv_fee'] += $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
}

// 送料無料チェック
if ($this->isDelivFree($productTypeId)) {
    $results['deliv_fee'] = 0;
}

の部分を

// 商品ごとの送料を加算
if (OPTION_PRODUCT_DELIV_FEE == 1) {
	$cartItems = $this->getCartList($productTypeId);
	$deliv_fee_cn = 0;
	foreach ($cartItems as $item) {
		//送料無料商品のみ	
		if($item['productsClass']['deliv_fee'] == 0){
			$results['deliv_fee'] = 0;
			$deliv_fee_cn += 0;
		}
		//通常商品のみ	
		if($item['productsClass']['deliv_fee'] == null){
			$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
			$deliv_fee_cn += 1;
		}
		//別途送料設定商品のみ	
		if($item['productsClass']['deliv_fee'] > 0){
			$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
			$deliv_fee_cn += 1;
		}
		//送料無料と通常商品が混在してる場合送料を0にする
		if($item['productsClass']['deliv_fee'] == null && $item['productsClass']['deliv_fee'] == 0){
			$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
			$deliv_fee_cn = 0;
		}		
	}
}

// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1
    && $deliv_fee_cn != 0
    && !SC_Utils_Ex::isBlank($deliv_pref)
    && !SC_Utils_Ex::isBlank($deliv_id)) {
    $results['deliv_fee'] += $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
}

// 送料無料チェック
if ($this->isDelivFree($productTypeId)) {
	//別途送料設定商品があるとき
	if($item['productsClass']['deliv_fee'] > 0){
		$results['deliv_fee'] = $item['productsClass']['deliv_fee'] * $item['quantity'];
	}else{
    		$results['deliv_fee'] = 0;
	}
}

に変更すればOK!

あとは管理画面の商品編集画面でOPTION_PRODUCT_DELIV_FEEの値を

  • 送料無料・・・0
  • 通常商品・・・NULL ※値を入力せず空にする
  • 別途送料・・・別途かかる送料の値段

にすればOK!!
テストしたけど一応これで大丈夫・・・?だと思います。

応用編:管理画面を使いやすいように変更する

応用編?というか一応
もし別途送料を設定することが無いというのであれば、
商品編集画面
のように管理画面を変更し使いやすく?することも可能です。
やりかたは

data/Smarty/templates/admin/products/product.tpl
(※商品編集(新規登録)画面のテンプレートです。)

<tr>
    <th>商品送料</th>
    <td>
<span class="attention"><!--{$arrErr.deliv_fee}--></span>
<input type="text" name="deliv_fee" value="<!--{$arrForm.deliv_fee|h}-->" size="6" class="box6" maxlength="<!--{$smarty.const.PRICE_LEN}-->" style="<!--{if $arrErr.deliv_fee != ""}-->background-color: <!--{$smarty.const.ERR_COLOR}-->;<!--{/if}-->"/>円
<span class="attention"> (半角数字で入力)</span>
<!--{if $smarty.const.OPTION_PRODUCT_DELIV_FEE != 1}--><br /><span class="attention">※現在無効です</span> (パラメータ OPTION_PRODUCT_DELIV_FEE)<!--{/if}-->
    </td>
</tr>

この部分を

<tr>
    <th>商品送料</th>
    <td>
<span class="attention"><!--{$arrErr.deliv_fee}--></span>
<input type="radio" name="deliv_fee" value="1" <!--{if $arrForm.deliv_fee|h == 1}-->checked="checked"<!--{/if}--> />送料無料 <input type="radio" name="deliv_fee" value="0" <!--{if $arrForm.deliv_fee|h == 0}-->checked="checked"<!--{/if}--> />通常送料
<!--{if $smarty.const.OPTION_PRODUCT_DELIV_FEE != 1}--><br /><span class="attention">※現在無効です</span> (パラメータ OPTION_PRODUCT_DELIV_FEE)<!--{/if}-->
    </td>
</tr>

のようにラジオボタンに変更し、

data/Smarty/templates/admin/products/confirm.tpl
(※商品編集(新規登録)確認画面のテンプレートです。)

<tr>
    <th>商品送料</th>
    <td>
<!--{$arrForm.deliv_fee|h}-->
円</td>
</tr>

の部分を

<tr>
    <th>商品送料</th>
    <td>
<!--{if $arrForm.deliv_fee|h == 1}-->
		送料無料
<!--{/if}-->
<!--{if $arrForm.deliv_fee|h == 0}-->
		通常送料
<!--{/if}-->
    </td>
</tr>

に変更し、
あとは先ほどのSC_Cartsession.php
の部分を

// 商品ごとの送料を加算
if (OPTION_PRODUCT_DELIV_FEE == 1) {
	$cartItems = $this->getCartList($productTypeId);
	$deliv_fee_cn = 0;
	foreach ($cartItems as $item) {
	//送料無料商品のみ	
	if($item['productsClass']['deliv_fee'] == 1){
		$results['deliv_fee'] = 0;
		$deliv_fee_cn = 0;
	}
	//通常商品のみ	
	if($item['productsClass']['deliv_fee'] == 0){
		$item['productsClass']['deliv_fee'] * $item['quantity'];
		$deliv_fee_cn++;
	}
	//送料無料と通常商品が混在してる場合送料を0にする
	if($item['productsClass']['deliv_fee'] == 0 && $item['productsClass']['deliv_fee'] == 1){
		$results['deliv_fee'] = 0;
		$deliv_fee_cn = 0;
	}
	}
	}

// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1
    && $deliv_fee_cn != 0
    && !SC_Utils_Ex::isBlank($deliv_pref)
    && !SC_Utils_Ex::isBlank($deliv_id)) {
    $results['deliv_fee'] += $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
}

// 送料無料チェック
if ($this->isDelivFree($productTypeId)) {
    $results['deliv_fee'] = 0;
}

に変更すればOK!

参考サイト

» 【EC-CUBE2.11.1】商品別送料の計算を変更する。
ありがとうございます。