EC-CUBE:割引クーポンを追加する

下記書籍をもとに書いています。詳しくは、本をお読みください。

「クーポン情報」ブロックを作成し、トップページなどでクーポン情報をお知らせできるようにする。

▼PCで表示

▼携帯で表示

▼スマートフォンで表示

1 データベースに新規テーブルを登録する。
(1)クーポンを登録するdtb_couponテーブルを作成する。
——————————————-
CREATE TABLE dtb_coupon(
coupon_id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
title text,
discount DECIMAL NOT NULL DEFAULT 0,
exp_start_date DATETIME,
exp_end_date DATETIME,
create_date DATETIME,
update_date DATETIME,
del_flg INT(2) NOT NULL DEFAULT 0
);
——————————————-

(2)使用したクーポンを登録するためのdtb_customer_couponテーブルを作成する。
——————————————-
CREATE TABLE dtb_customer_coupon(
customer_coupon_id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
customer_id INT(11) NOT NULL,
coupon_id INT(11) NOT NULL,
order_id INT(11) NOT NULL,
create_date DATETIME,
update_date DATETIME,
del_flg INT(2) NOT NULL DEFAULT 0
);
——————————————-

(3)クーポン情報を一時受注テーブルに登録可能にするために、dtb_order_tempにカラムを追加する。
——————————————-
フィールド:coupon
種別:TEXT
——————————————-

2 管理画面からクーポンを登録できるようにする。

(1)下記ファイルを新規作成
 ■html/admin/contents/coupon.php

 <?php
 // {{{ requires
 require_once '../require.php';
 require_once CLASS_EX_REALDIR . 'page_extends/admin/contents/LC_Page_Admin_Contents_Coupon_Ex.php';

// }}}
 // {{{ generate page

$objPage = new LC_Page_Admin_Contents_Coupon_Ex();
 register_shutdown_function(array($objPage, 'destroy'));
 $objPage->init();
 $objPage->process();
 ?>

 ■data/class_extends/page_extends/admin\contents/LC_Page_Admin_Contents_Coupon_Ex.php

 <?php
 // {{{ requires
 require_once CLASS_REALDIR . 'pages/admin/contents/LC_Page_Admin_Contents_Coupon.php';

class LC_Page_Admin_Contents_Coupon_Ex extends LC_Page_Admin_Contents_Coupon {

// }}}
 // {{{ functions

/**
 * Page を初期化する.
 *
 * @return void
 */
 function init() {
 parent::init();
 }

/**
 * Page のプロセス.
 *
 * @return void
 */
 function process() {
 parent::process();
 }

/**
 * デストラクタ.
 *
 * @return void
 */
 function destroy() {
 parent::destroy();
 }
 }
 ?>
 

 ■data/class/pages/admin/contents/LC_Page_Admin_Contents_Coupon.php
 ■data/Smarty/templates/admin/contents/coupon.tpl

(2)■data/Smarty/templates/admin/contents/subnavi.tplに追加する。

 <li<!--{if $tpl_subno == 'coupon'}--> class="on"<!--{/if}--> id="navi-contents-coupon"><a href="<!--{$smarty.const.ROOT_URLPATH}--><!--{$smarty.const.ADMIN_DIR}-->contents/coupon.php"><span>クーポン管理</span></a></li>

3 class/helper内のデータベース関連ファイルに追加

(1)■data/class/helper/SC_Helper_DB.phpの最下部sfHasProductClassの次に、getCustomerCouponメソッドを追加する。

 function getCustomerCoupon($customer_id) {
 $objQuery   = new SC_Query();

// 使用可能なクーポンを取得する
 // dtb_customer_couponに使用された(del_flg=0)クーポンが登録されていないか
 // 削除されたクーポンでないか
 $col = "dtb_coupon.*";
 $from = "dtb_coupon";
 $where = "";
 $where .= SC_Utils_Ex::sfCouponExpDate('dtb_coupon.',1);
 $where .= " ";
 $where .= "AND ";
 $where .= "dtb_coupon.del_flg = 0 ";
 $where .= "AND ";
 $where .= "dtb_coupon.coupon_id ";
 $where .= "NOT IN ";
 $where .= "( ";
 $where .=   "SELECT ";
 $where .=   "coupon_id ";
 $where .=   "FROM ";
 $where .=   "dtb_customer_coupon ";
 $where .=   "inner join ";
 $where .=   "dtb_customer ";
 $where .=   "on dtb_customer.customer_id = dtb_customer_coupon.customer_id ";
 $where .=   "WHERE ";
 $where .=   "dtb_customer.customer_id = ? and dtb_customer_coupon.del_flg = 0";
 $where .= ") ";
 $arrval = array($customer_id);
 $where_all = $where;
 $arrAll = $objQuery->select($col, $from, $where_all, $arrval);
 return $arrAll;
 }

//クーポンの情報を取得する
 function getCoupon($coupon_id){
 $objQuery   = new SC_Query();
 $coupon = $objQuery->select("title,discount","dtb_coupon","coupon_id = ? and del_flg = 0",array($coupon_id));
 return $coupon[0];

}

(2)■data/class/helper/SC_Helper_Purchase.php
851行目あたり 「新規受付の場合は対応状況・・・」のコメントアウトの前に追加

 // 使用したクーポンをdtb_customer_couponテーブルに登録する
 // POSTされるクーポンIDはカンマ区切りの文字列なので、カンマで分割
 $coupon = explode(',',$arrParams['coupon']);
 foreach($coupon as $val){
 if($val != ""){
 $sqlval['customer_id'] =
 SC_Utils_Ex::isBlank($arrValues['customer_id'])
 ? 0 : $arrValues['customer_id'];
 $sqlval['coupon_id'] = $val;
 $sqlval['order_id'] = $order_id;
 $sqlval['create_date'] = "now()";
 $sqlval['update_date'] = "now()";
 $objQuery->insert("dtb_customer_coupon",$sqlval);
 }
 }

(3)■data/class/util/SC_Utils.php
721行目あたり /* 規格分類の件数取得 */function sfGetClassCatCountメソッドの後に追加

 /*
 * クーポンが使用できる期間内にあるか判定
 *
 */
 public static function sfCouponExpDate($prefix = 'dtb_coupon.',$check = 0) {
 //check == 0 ならnow()判定
 //check == 1 ならcurrent_date判定
 if($check == 0){
 return " CASE WHEN {$prefix}exp_start_date IS NOT NULL AND {$prefix}exp_end_date IS NOT NULL THEN now() BETWEEN {$prefix}exp_start_date AND {$prefix}exp_end_date ELSE 1=1 END ";
 }else{
 return " CASE WHEN {$prefix}exp_start_date IS NOT NULL AND {$prefix}exp_end_date IS NOT NULL THEN current_date() BETWEEN {$prefix}exp_start_date AND {$prefix}exp_end_date ELSE 1=1 END ";
 }
 }

4 お支払い方法・お届け時間等の指定画面でクーポンを利用できるようにする。
下記ファイルにクーポン関連のコードを追加する
 ■data/class/pages/shopping/LC_Page_Shopping_Payment.php
 ■data/class/pages/shopping/LC_Page_Shopping_Confirm.php
 ■data/Smarty/templates/default/shopping/payment.tpl(PC)
 ■data/Smarty/templates/default/shopping/confirm.tpl(PC)
 ■data/Smarty/templates/mobile/shopping/payment.tpl(携帯)
 ■data/Smarty/templates/mobile/shopping/confirm.tpl(携帯)
 ■data/Smarty/templates/sphone/shopping/payment.tpl(スマートフォン)
 ■data/Smarty/templates/sphone/shopping/confirm.tpl(スマートフォン)

5 割引後の合計金額の計算。手数料と送料を割引の対象にしない。
■data/class/SC_CartSession.php 666行目あたり

 // 合計を計算
 $results['total'] = $results['subtotal'];
 $results['total'] += $results['deliv_fee'];
 $results['total'] += $charge;
 $results['total'] -= $discount;

↓(変更)

// 合計を計算
 // 割引後の金額が0円以下になった場合0に修正
 $results['total'] = $results['subtotal'];
 $results['total'] -= $discount;
 if($results['total'] < 0) $results['total'] = 0;
 $results['total'] += $results['deliv_fee'];
 $results['total'] += $charge;

6 MYページでクーポンを表示する。
下記ファイルにクーポン関連のコードを追加する
 ■data/class/pages/mypage/LC_Page_Mypage.php
 ■data/Smarty/templates/default/mypage/index.tpl(PC)
 ■data/Smarty/templates/mobile/mypage/index.tpl(携帯)
 ■data/Smarty/templates/sphone/mypage/index.tpl(スマートフォン)

7 受注管理で金額表示。キャンセル時にクーポンの履歴を戻す。
(1)■data/class/pages/admin/order/LC_Page_Admin_Order_Edit.php

下記を変更

 // 合計
 $arrValues['total'] = $subtotal - $arrValues['discount'] + $arrValues['deliv_fee'] + $arrValues['charge'];

↓(変更)

// 割引
 $arrValues['total'] = $subtotal - $arrValues['discount'];
 //割引後の金額がマイナスになった場合0に戻す
 if($arrValues['total'] < 0) $arrValues['total'] = 0;
 // 合計
 $arrValues['total'] +=  $arrValues['deliv_fee'] + $arrValues['charge'];

 「// 受注テーブルの更新 $order_id = $objPurchase->registerOrder($order_id, $arrValues);」の次に追加

 //キャンセル時には使用したクーポン履歴を論理削除
 //再度キャンセル以外のステータスに戻してもクーポンは使用状態にはならないので注意
 if($arrValues['status']==3){
 //同じorder_idのクーポン履歴を削除
 $sqlVal['del_flg'] = 1;
 $where = 'order_id = ?';
 $objQuery->update('dtb_customer_coupon',$sqlVal,$where,array($arrValues['order_id']));
 }

(2)■data/class/pages/admin/order/LC_Page_Admin_Order_Status.php
217行目あたりに追加

 //キャンセル時には使用したクーポン履歴を論理削除
 //再度キャンセル以外のステータスに戻してもクーポンは使用状態にはならないので注意
 if($statusId == 3){
 //同じorder_idのクーポン履歴を削除
 $sqlVal['del_flg'] = 1;
 $where = 'order_id = ?';
 $objQuery->update('dtb_customer_coupon',$sqlVal,$where,array($orderId));
 }

8 クーポン情報をお知らせするブロックを作成する

(1)拡張ファイル等の作成
 ■html/frontparts/bloc/coupon.php

 <?php

// {{{ requires
 require_once realpath(dirname(__FILE__)) . '/../../require.php';
 require_once CLASS_EX_REALDIR . 'page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Coupon_Ex.php';

// }}}
 // {{{ generate page

$objPage = new LC_Page_FrontParts_BLoc_Coupon_Ex();
 $objPage->blocItems = $params['items'];
 register_shutdown_function(array($objPage, "destroy"));
 $objPage->init();
 $objPage->process();
 ?>

 ■data/class_extends/page_extends/frontparts/bloc/LC_Page_FrontParts_Bloc_Coupon_Ex.php

 <?php

// {{{ requires
 require_once CLASS_REALDIR . 'pages/frontparts/bloc/LC_Page_FrontParts_Bloc_Coupon.php';

class LC_Page_FrontParts_Bloc_Coupon_Ex extends LC_Page_FrontParts_Bloc_Coupon {

// }}}
 // {{{ functions

/**
 * Page を初期化する.
 *
 * @return void
 */
 function init() {
 parent::init();
 }

/**
 * Page のプロセス.
 *
 * @return void
 */
 function process() {
 parent::process();
 }

/**
 * デストラクタ.
 *
 * @return void
 */
 function destroy() {
 parent::destroy();
 }
 }
 ?>

 ■data/class/page/frontparts/bloc/LC_Page_FrontParts_Bloc_Coupon.php

 <?php

// {{{ requires
 require_once CLASS_REALDIR . 'pages/frontparts/bloc/LC_Page_FrontParts_Bloc.php';

class LC_Page_FrontParts_Bloc_Coupon extends LC_Page_FrontParts_Bloc {

// }}}
 // {{{ functions

/**
 * Page を初期化する.
 *
 * @return void
 */
 function init() {
 parent::init();
 }

/**
 * Page のプロセス.
 *
 * @return void
 */
 function process() {
 $this->action();
 $this->sendResponse();
 }

/**
 * Page のアクション.
 *
 * @return void
 */
 function action() {

// データベースから取得
 $objQuery = SC_Query_Ex::getSingletonInstance();
 $this->arrRet = array();

//クーポン情報を取得
 $arrRet = $objQuery->select('*','dtb_coupon','del_flg = 0 and exp_end_date >= current_date');

//データベースから取得できたか
 if(isset($arrRet)){
 $this->arrRet = $arrRet;
 }
 }

/**
 * デストラクタ.
 *
 * @return void
 */
 function destroy() {
 parent::destroy();
 }
 }
 ?>

(2)テンプレートの作成

PC用 ■data/Smarty/templates/default/frontparts/bloc/coupon.tpl


<!--▼クーポン情報-->

<!--{if count($arrRet) > 0}-->

<div id="coupon_area" class="bloc_outer">

<h2>クーポン情報</h2>

<div class="bloc_body">

<!--{section name=cnt loop=$arrRet}-->

<div class="title"><!--{$arrRet[cnt].title|h}--></div>

<div class="discount">割引額:<span class="attentionSt"><!--{$arrRet[cnt].discount|h}-->円</span></div>

<div class="date">期間:<!--{$arrRet[cnt].exp_start_date|date_format:"%x"}-->~<!--{$arrRet[cnt].exp_end_date|date_format:"%x"}--></div>

<!--{/section}-->

<div class="comment">

会員の方は、お買い物の際、クーポンがご利用になれます。<br />

MYページで利用可能なクーポンをご確認いただけます。

</div>

</div>

</div>

<!--{/if}-->

携帯用 ■data/Smarty/templates/mobile/frontparts/bloc/coupon.tpl

 <!--▼クーポン情報-->
 <!--{if count($arrRet) > 0}-->
 <hr>
 <h3>クーポン情報</h3><br>
 <!--{section name=cnt loop=$arrRet}-->
 <!--{$arrRet[cnt].title|h}--><br />
 割引額:<!--{$arrRet[cnt].discount|h}-->円<br />
 期間:<!--{$arrRet[cnt].exp_start_date|date_format:"%x"}-->~<!--{$arrRet[cnt].exp_end_date|date_format:"%x"}-->
 <hr>
 <!--{/section}-->
 会員の方は、お買い物の際クーポンがご利用になれます。<br />
 MYページで利用可能なクーポンをご確認いただけます。
 <!--{/if}-->

スマートフォン用 ■data/Smarty/templates/sphone/frontparts/bloc/coupon.tpl


<!-- ▼クーポン情報 -->

<!--{if count($arrRet) > 0}-->

<section id="coupon_area">

<h2 class="title_block">クーポン情報</h2>

<ul class="couponlist">

<!--{section name=cnt loop=$arrRet}-->

<li>

<span class="fb"><!--{$arrRet[cnt].title|h}--></span><br />

割引額:<span class="attentionSt"><!--{$arrRet[cnt].discount|h}-->円</span><br />

期間:<span class="coupon_date"><!--{$arrRet[cnt].exp_start_date|date_format:"%x"}-->~<!--{$arrRet[cnt].exp_end_date|date_format:"%x"}--></span>

</li>

<!--{/section}-->

</ul>

<div class="comment">

会員の方は、お買い物の際クーポンがご利用になれます。<br />

MYページで利用可能なクーポンをご確認いただけます。

</div>

</section>

<!--{/if}-->

(3)CSSに追加
PC用 ■html/user_data/packages/default/css/bloc.css

 /* ===============================================
 ▼クーポン情報
 =============================================== */
 #coupon_area {
 margin-bottom:20px;
 }
 #coupon_area h2 {
 color:#E75019;
 padding:4px 10px;
 border-top:#F90 1px solid;
 border-left:#F90 10px solid;
 border-right:#ccc 1px solid;
 background-color:#FEE39E;
 }
 #coupon_area .bloc_body {
 padding:10px;
 }
 #coupon_area .title {
 color:#FFF;
 background-color:#E75019;
 padding:2px 4px;
 margin-bottom:5px;
 }
 #coupon_area .discount {
 margin-bottom:5px;
 }
 #coupon_area .date {
 margin-bottom:5px;
 }
 #coupon_area .comment {
 background-color: #FFEBD7;
 border:#ddd 1px solid;
 padding:5px;
 margin-bottom:5px;
 }

スマートフォン用 ■html/user_data/packages/sphone/css/bloc.css

 /*-----------------------------------------------
 クーポン情報
 ----------------------------------------------- */
 #coupon_area{
 margin-bottom: 20px;
 }
 #coupon_area ul{
 }
 #coupon_area li, #coupon_area .comment {
 display:block;
 clear:both;
 padding:10px;
 line-height:1.3;
 background-color:#FEFEFE;
 background: -moz-linear-gradient(center top, #FEFEFE 0%,#EEEEEE 100%);
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #FEFEFE),color-stop(1, #EEEEEE));
 border-top:#FFF solid 1px;
 border-bottom:#CCC solid 1px;
 }
 #coupon_area .coupon_date{
 clear:both;
 font-size:12px;
 letter-spacing:0.1em;
 }

(4)データベースのdtb_blocにPC用(device_type_id=10)、携帯用(device_type_id=1)、スマートフォン用(device_type_id=2)のブロックを登録する。
PC用
——————————————
device_type_id:10
bloc_id:13(環境に応じて)
bloc_name:クーポン情報
tpl_path:coupon.tpl
filename:coupon
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/coupon.php
deletable_flg:0
——————————————

携帯用
——————————————
device_type_id:1
bloc_id:8(環境に応じて)
bloc_name:クーポン情報
tpl_path:coupon.tpl
filename:coupon
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/coupon.php
deletable_flg:0
——————————————

スマートフォン用
——————————————
device_type_id:2
bloc_id:11(環境に応じて)
bloc_name:クーポン情報
tpl_path:coupon.tpl
filename:coupon
create_date:作成日時
update_date:作成日時
php_path:frontparts/bloc/coupon.php
deletable_flg:0
——————————————