EC-CUBE:送料のなんちゃって個別設定

EC-CUBEの送料に関して、以下の設定を追加したのでメモ。
EC-CEBE Ver 2.41

  1. 送料が無料の商品を登録(物品とコンテンツ系商品が混在する場合など)
  2. 送料は配送設定画面にて決定する。(ただしコンテンツ系のみの場合は¥0)

このバージョンのEC-CUBEには中途半端に個別送料設定に関するシステムが組み込まれています。
もともと組み込まれている送料個別設定だと、個別に設定された送料を、商品数分すべて上乗せするという、あまり想定出来ないような仕組みになっています。例えば送料500円の商品を3つ買うと、送料1500円といった具合です。正直、微妙です。これだと、送料無料の商品だと問題ないですが、送料が必要な商品の場合にとても高くなるなど支障が出てしまいます。
そういったことで、今回は送料無料のフラグを立てることにしました。詳細は以下より。

管理画面の商品登録ページに商品無料設定を追加
管理画面の商品登録ページにはもともと個別送料設定欄がありますが、コメントアウトされています。それを外せばOKですね。今回はこのパラメータを商品無料フラグとして利用することにしました。変数名は$deliv_feeです。admin/products/product.tpl及びconfirm.tplを編集します。今回はフラグなので、「送料無料設定(無料=1、通常送料=0)」としました。これだと、すでに登録してある物品に対してなにも変更する必要がありません。また、すでにあるパラメータ「deliv_fee」をそのまま利用することができます。
SC_Helper_Db.phpの編集
SC_Helper_Db.phpを直接編集せずに、SC_Helper_Db_Ex.phpで編集するようにします。送料の最終計算をするページは、shopping/confirm.phpです。 その親クラスであるLC_Page_Shopping_Confirm.phpを見てみますと、以下のようになっています。

// カート集計処理
        $objDb->sfTotalCart($this, $objCartSess, $arrInfo);
        // 一時受注テーブルの読込
        $arrData = $objDb->sfGetOrderTemp($uniqid);
        // カート集計を元に最終計算
        $arrData = $objDb->sfTotalConfirm($arrData, $this, $objCartSess, $arrInfo, $objCustomer, $objCampaignSess);

sfTotalCart関数で、$objPageオブジェクトのarrProductsClass配列に、商品情報が格納されて返されます。そして、sfTotalConfirm関数の第2因数で$thisとして引用しています。
sfTotalConfirm関数は、SC_Helper_Db.phpの中で定義されています。
その中に、

        // 商品ごとの送料が有効の場合
        if (OPTION_PRODUCT_DELIV_FEE == 1) {
            //$arrData['deliv_fee']+= $objCartSess->getAllProductsDelivFee();
        }

という箇所がありますが、この中の

$objCartSess->getAllProductsDelivFee();

はSESSION["cart"]にdeliv_feeが無いので動作しません。
代わりに、以下で商品ごとの商品送料を求めることができます。

$objPage->tpl_total_deliv_fee:商品数に応じた送料(商品個別で登録した送料の総計)
$objPage->arrProductsClass[アイテムの種類の配列数]["deliv_fee"]:商品ごとの送料(アイテムの種類ごとに配列に格納されています)

今回は、コンテンツ系アイテムが1つだけという設定でしたので、アイテムの種類が1種類で尚且つ、それがコンテンツ系アイテムの場合のみ、送料が0円になればよく、それ以外は配送設定での料金適用でしたので、以下のようにしました。

// 配送業者の送料が有効の場合
        if (OPTION_DELIV_FEE == 1) {
            // 商品の種類が1種類で尚且つ送料無料設定が1以上の場合は送料0
            if(count($objPage->arrProductsClass) == 1 && $objPage->tpl_total_deliv_fee >= 1){
                $arrData['deliv_fee'] = 0;
            }else{
                $arrData['deliv_fee'] += $this->sfGetDelivFee($arrData);
            }
        }

もしもコンテンツ系アイテムが複数ある場合は、for($i=0,$iarrProductsClass)-1,$i++)など、すべて送料無料フラグがある場合とそうでない場合で分岐すればと思います。

今回は、単純なものでしたが、もしも送料が商品ごとにバラバラで設定したいなどといった場合は、また違う処理をする必要があるので別の機会に実装したいと思います。今回は最も修正箇所が少ないという方法(だと思う)で実装しました。