EC-CUBEのカスタマイズ ギフト包装・のし対応
EC-CUBEの2.1.2の注文画面で、ギフト包装や、リボン、のしを選択できるようにカスタマイズしてみた。
その他、概要はこんな感じ。
- ギフト包装の種類は、管理画面>基本情報管理>マスタデータ管理で変更可能にする。
- ギフト包装が有料の場合にも対応する。ただし、有料ギフト包装の金額はポイント対象外。
- ギフト包装の金額は、管理画面>基本情報管理>マスタデータ管理で変可能にする。
- MYページの購入履歴画面や注文完了メール内に、選択したギフト包装の種類と金額を載せる。
ロジックの変更はするけど、それは全部継承で対応する方針で。親のクラスには手を入れない。
ちょっと長いので、順番にやってきます。
まずは、データの準備から。
1.ギフト包装の種類のマスタテーブルを作る
以下SQLでギフト用のマスタテーブルを作る。
CREATE TABLE `mtb_gift` ( `id` smallint(6) NOT NULL default '0', `name` text, `rank` smallint(6) NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DBやEC-CUBEのWikiにあるテーブル仕様書をみてみると、mtb_*がマスタ系になっている。だいたいみんな同じ構造している。
mtb_*の名称が管理画面>基本情報管理>マスタデータ管理で変更できるが、mtb_pref、mtb_zip、mtb_constants はマスタ管理からはずされている。
それについてはLC_Page_Admin_Basis_Masterdata.php::getMasterDataNames() に書いてあった。
2.ギフト包装の種類を入れる。
管理画面>基本情報管理>マスタデータ管理で、さっき作ったmtb_giftを選択して、ギフト包装の種類を登録していく。
ID=0はギフトなしとして使うので、登録しない。1から登録する。
3.受注データ内に、ギフト情報をどのように格納するか
受注テーブル(dtb_order)や、一時的な受注テーブル(dtb_order_temp)を見てみると、text型のmemo1〜memo10という汎用項目として使える列があって、memo1〜4あたりは既に使ってるっぽい。
なので、memo09とmemo10を使ってギフト情報を格納することにした。
- memo09・・・ギフト包装の種類。0はギフト包装なし。
- memo10・・・受注したときのギフト包装の価格。
4.ギフト包装の税込金額を定数で設定しておく
以下SQLで新しく定数を登録する。
INSERT INTO `mtb_constants` values('GIFT_PRICE', '577', '523', 'ギフト包装の税込価格');
- 1つ目のidが定数名。
- 2つ目のnameに入れるのが定数の値。今回の場合はギフト包装の税込金額。
- 3番目のrankに入れるのが管理画面での表示順。今入っているレコードの最大+1だと一番下に表示される。
- 4番目のremarkに入れるのが管理画面でパラメータ入力欄の上に灰色で小さく出るパラメータの説明文。
次に、管理画面>基本情報管理>マスタデータ管理へアクセスし、一回保存する。
そうすると、「マスタテーブル」⇒「定数設定ばっかりするPHPファイル」に変換することでDBをキャッシュするようにしてるファイルが更新される。
data/cache/mtb_*.phpが、それら。
これで、ギフト包装の価格が変わっても管理画面で変更できるー。
5.お支払方法・お届け時間等の指定画面
PCサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/shopping/payment.tpl
内に以下を加える。
<!--{assign var=key value="memo09"}--> <span class="attention"><!--{$arrErr[$key]}--></span> <select name="<!--{$key}-->" style="<!--{$arrErr[$key]|sfGetErrorColor}-->"> <option value="0" selected="selected">ギフトなし</option> <!--{html_options options=$arrGift selected=$arrForm[$key].value}--> </select>
モバイルサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/mobile/shopping/deliv_date.tpl
内に以下を加える。
<!--{assign var=key value="memo09"}--> <!--{if $arrErr[$key] != ""}--> <font color="red"><!--{$arrErr[$key]}--></font> <!--{/if}--> <select name="<!--{$key}-->"> <option value="0">ギフトなし</option> <!--{html_options options=$arrGift selected=$arrForm[$key].value}--> </select>
ページクラスの拡張
data/class_extends/page_extends/shopping/LC_Page_Shopping_Payment_Ex.php
init()、lfInitParam()、lfSetOrderTempData()をオーバーライドする。
<? function init() { parent::init(); $this->tpl_title = "お支払方法・お届け時間・ギフト包装の指定"; $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } function lfInitParam() { parent::lfInitParam(); $this->objFormParam->addParam( "ギフト・のし", "memo09", INT_LEN, "n", array( "MAX_LENGTH_CHECK", "NUM_CHECK") ); } //一時受注テーブルからの情報を格納する function lfSetOrderTempData($uniqid) { $objQuery = new SC_Query(); $col = "payment_id, use_point, deliv_time_id, message, point_check, deliv_date, memo09"; $from = "dtb_order_temp"; $where = "order_temp_id = ?"; $arrRet = $objQuery->select($col, $from, $where, array($uniqid)); // DB値の取得 $this->objFormParam->setParam($arrRet[0]); return $this->objFormParam; } ?>
6.ご入力内容の確認画面
こんな感じで、注文内容の欄に、前の画面で選択したギフト包装の種類と価格を含めるようにする。
ギフトなしの場合はこの行自体ださないようにする。
PCサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/shopping/confirm.tpl
<!--{if $arrData.memo09 gt 0}--> <tr> <th colspan="4" class="resulttd">ギフト包装 : <!--{$arrGift[$arrData.memo09]}--></th> <td class="pricetd"><!--{$smarty.const.GIFT_PRICE|number_format}-->円</td> </tr> <!--{/if}-->
モバイルサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/mobile/shopping/confirm.tpl
<!--{if $arrData.memo09 gt 0}-->ギフト包装(<!--{$arrGift[$arrData.memo09]}-->):<!--{$smarty.const.GIFT_PRICE|number_format}--><br><!--{/if}-->
あと、その下のほうにこれも。
<input type="hidden" name="memo09" value="<!--{$arrData.memo09}-->">
ページクラスの拡張
data/class_extends/page_extends/admin/order/LC_Page_Shopping_Confirm_Ex.php
init()をオーバーライドする。
<? function init() { parent::init(); $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } ?>
お会計ロジックを拡張
data/class_extends/helper_extends/SC_Helper_DB_Ex.php
sfTotalConfirm()をオーバーライド。
<? /** * 集計情報を元に最終計算を行う. * * @param array $arrData 各種情報 * @param LC_Page $objPage LC_Page インスタンス * @param SC_CartSession $objCartSess SC_CartSession インスタンス * @param array $arrInfo 店舗情報の配列 * @param SC_Customer $objCustomer SC_Customer インスタンス * @return array 最終計算後の配列 */ function sfTotalConfirm($arrData, &$objPage, &$objCartSess, $arrInfo, $objCustomer = "") { $arrData = parent::sfTotalConfirm($arrData, &$objPage, &$objCartSess, $arrInfo, $objCustomer = ""); // ギフト包装の計算。0はギフト包装なしのこと。 if ( intval( $arrData["memo09"] ) > 0 ) { $arrData['payment_total'] += GIFT_PRICE; $arrData['memo10'] = GIFT_PRICE; } else { $arrData['memo10'] = 0; } return $arrData; } ?>
7.購入履歴画面
PCサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/mypage/history.tpl
<!--{if $arrDisp.memo09 != "" && $arrDisp.memo09 gt 0}--> <tr> <th colspan="4" class="resulttd">ギフト包装 : <!--{$arrGift[$arrDisp.memo09]}--></th> <td class="pricetd"><!--{$arrDisp.memo10|escape|number_format}-->円</td> </tr> <!--{/if}-->
モバイルサイトのテンプレートの修正
data/Smarty/templates/テンプレート名/mobile/mypage/history_detail.tpl
<!--{if $arrDisp.memo09 != "" && $arrDisp.memo09 gt 0}--> ギフト包装(<!--{$arrGift[$arrDisp.memo09]}-->):<!--{$arrDisp.memo10|escape|number_format}-->円<br> <!--{/if}-->
ページクラスの拡張
data/class_extends/page_extends/mypage/LC_Page_Mypage_History_Ex.php
init()、lfGetOrderData()をオーバーライド。
<? function init() { parent::init(); $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } //受注詳細データの取得 function lfGetOrderData($order_id) { //受注番号が数字であれば if(SC_Utils_Ex::sfIsInt($order_id)) { // DBから受注情報を読み込む $objQuery = new SC_Query(); $col = "order_id, create_date, payment_id, subtotal, tax, use_point, add_point, discount, "; $col .= "deliv_fee, charge, payment_total, deliv_name01, deliv_name02, deliv_kana01, deliv_kana02, "; $col .= "deliv_zip01, deliv_zip02, deliv_pref, deliv_addr01, deliv_addr02, deliv_tel01, deliv_tel02, deliv_tel03, deliv_time_id, deliv_date, memo09, memo10 "; $from = "dtb_order"; $where = "order_id = ?"; $arrRet = $objQuery->select($col, $from, $where, array($order_id)); $arrOrder = $arrRet[0]; // 受注詳細データの取得 $arrRet = $this->lfGetOrderDetail($order_id); $arrOrderDetail = SC_Utils_Ex::sfSwapArray($arrRet); $arrData = array_merge($arrOrder, $arrOrderDetail); } return $arrData; } ?>
モバイルサイト用に、こっちもおなじように拡張。
data/class_extends/page_extends/mypage/LC_Page_Mypage_HistoryDetail_Ex.php
<? function mobileInit() { parent::mobileInit(); $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } //受注詳細データの取得 function lfGetOrderData($order_id) { //受注番号が数字であれば if(SC_Utils_Ex::sfIsInt($order_id)) { // DBから受注情報を読み込む $objQuery = new SC_Query(); $col = "order_id, create_date, payment_id, subtotal, tax, use_point, add_point, discount, "; $col .= "deliv_fee, charge, payment_total, deliv_name01, deliv_name02, deliv_kana01, deliv_kana02, "; $col .= "deliv_zip01, deliv_zip02, deliv_pref, deliv_addr01, deliv_addr02, deliv_tel01, deliv_tel02, deliv_tel03, deliv_time_id, deliv_date, memo09, memo10 "; $from = "dtb_order"; $where = "order_id = ?"; $arrRet = $objQuery->select($col, $from, $where, array($order_id)); $arrOrder = $arrRet[0]; // 受注詳細データの取得 $arrRet = $this->lfGetOrderDetail($order_id); $arrOrderDetail = SC_Utils_Ex::sfSwapArray($arrRet); $arrData = array_merge($arrOrder, $arrOrderDetail); } return $arrData; } ?>
8.受注完了メール
- -
小 計 ¥ 3,021 (うち消費税 ¥144)
値引き ¥ 1,195
送 料 ¥ 1,000
手数料 ¥ 300
ギフト包装:包装+リボン ¥ 577
===============================================================
合 計 ¥ 3,703
===============================================================
こんな感じで、受注完了メールに選択したギフト包装の種類と、価格を載せるようにする。
PCサイト用受注完了メールテンプレートの修正
data/Smarty/templates/テンプレート名/mail_templates/order_mail.tpl
ギフト包装:<!--{$arrOrder.gift_type}--> ¥ <!--{$arrOrder.gift_price|number_format|default:0}-->
モバイルサイト用受注完了メールテンプレートの修正
data/Smarty/templates/テンプレート名/mobile/mail_templates/order_mail.tpl
こっちもおなじ。
ギフト包装:<!--{$arrOrder.gift_type}--> ¥ <!--{$arrOrder.gift_price|number_format|default:0}-->
受注完了メール送信ロジックの拡張
data/class_extends/helper_extends/SC_Helper_Mail_EX.php
コンストラクタと、sfSendOrderMail()をオーバーライド。
<? function SC_Helper_Mail_Ex() { parent::SC_Helper_Mail(); $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } /* 受注完了メール送信 */ function sfSendOrderMail($order_id, $template_id, $subject = "", $header = "", $footer = "", $send = true) { // 省略・・・ // 都道府県変換 $objPage->arrOrder['deliv_pref'] = $this->arrPref[$objPage->arrOrder['deliv_pref']]; // ↓このあたりに追加。 // ギフト包装変換 $objPage->arrOrder['gift_type'] = $this->arrGift[$arrOrder['memo09']]; $objPage->arrOrder['gift_price'] = $arrOrder['memo10']; // ↑このあたりに追加。 $objPage->arrOrderDetail = $arrOrderDetail; // 省略・・・ } ?>
9.管理側受注管理
こんなかんじで、管理画面>受注管理>受注管理>受注履歴編集 で、ギフト包装の情報が見れたり、変更できたりできるようにする。
有料に設定したid=1以上のギフト包装から、ギフトなしに変更(その逆も)して「計算結果の確認」や「この内容で変更する」を押したときに金額が変わることにも対応する。
管理画面>受注管理>ステータス管理 で受注番号を選択して出るポップアップのほうも対応する。
テンプレートの修正
data/Smarty/templates/テンプレート名/admin/order/edi.tpl
手数料の行の下あたり。
<tr bgcolor="#ffffff" class="fs12n"> <td colspan="5" align="right">ギフト包装 : <!--{assign var=key value="memo09"}--> <span class="red12"><!--{$arrErr[$key]}--></span> <select name="<!--{$key}-->" style="<!--{$arrErr[$key]|sfGetErrorColor}-->"> <option value="0">ギフトなし</option> <!--{html_options options=$arrGift selected=$arrForm[$key].value}--> </td> <td align="right"><!--{$arrForm.memo10.value|number_format}--> 円</td> </tr>
data/Smarty/templates/テンプレート名/admin/order/disp.tpl
手数料の行の下あたり。
<tr bgcolor="#ffffff" class="fs12n"> <td colspan="4" align="right">ギフト包装 : <!--{if $arrDisp.memo09 != "" && $arrDisp.memo09 gt 0}--> <!--{$arrGift[$arrDisp.memo09]}--> <!--{else}--> ギフトなし <!--{/if}--> </td> <td align="right"><!--{$arrDisp.memo10|number_format}--> 円</td> </tr>
ページクラスの拡張
data/class_extends/page_extends/admin/order/LC_Page_Admin_Order_Edit_Ex.php
init()、lfInitParam()、lfCheek()をオーバーライド。
<? function init() { parent::init(); $masterData = new SC_DB_MasterData_Ex(); $this->arrGift = $masterData->getMasterData( "mtb_gift", array( "id", "name", "rank" ) ); } function lfInitParam() { parent::lfInitParam(); $this->objFormParam->addParam("ギフト・のし", "memo09", INT_LEN, "n", array("EXIST_CHECK", "MAX_LENGTH_CHECK", "NUM_CHECK"), '0' ); $this->objFormParam->addParam("ギフト包装料金", "memo10" ); } /* 計算処理 */ function lfCheek($arrInfo) { $arrErr = parent::lfCheek( $arrInfo ); $arrVal = $this->objFormParam->getHashArray(); // ギフト包装料金の計算。合計とお支払い合計を計算しなおしす。0はギフト包装なしのこと。 if ( intval( $_POST["memo09"] ) > 0 ) { // 合計 $arrVal['total'] += GIFT_PRICE; // お支払い合計 $arrVal['payment_total'] = $arrVal['total'] - ($arrVal['use_point'] * POINT_VALUE); $arrVal['memo10'] = GIFT_PRICE; } else { $arrVal['memo10'] = 0; } $this->objFormParam->setParam( $arrVal ); return $arrErr; } ?>
これでおしまい。
長かった・・・。
あとは、ポイントのON/OFF機能とか、次期バージョンで載ってるといいなー。