Latest Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ポイントに有効期限を設ける

ポイントに有効期限を設ける=「最終購買日から○ヶ月以上経過した会員のポイントを0にする」だけなら、処理としては簡単です。
dtb_customer(顧客マスタ)のlast_buy_date(最終購入日)から○ヶ月(以上)経過したポイントを0にしてやればいいだけです。
こんな感じ。(postgreSQLの場合)

(SQL1)
//最終購買日から24ヶ月以上経過した会員のポイントを0にする
update dtb_customer set point=0
where CAST(last_buy_date + '24 months' AS timestamp) <= CURRENT_TIMESTAMP ;

(SQL2)
//特定の会員のポイントを0にする
update dtb_customer set point=0
where customer_id=?;

これを毎日0時(SQL1)とか、任意のタイミング(SQL2)で走らせてやれば良いです。
それよりも問題は、それに伴って、どういう表示をするか・どういう運用をするか、であって、その決めごとによってしなければならないことはとても増えてしまいます。

・0になった(或いはなる)会員に対してどのタイミングで告知するか
    例えば、
    1) ログイン時に最初に表示して告知する。
    2) カート画面、MYページなど、(下記の「了解」ボタンを押下するまで)ポイント表示する画面やブロックすべてに表示する。
    3) 「0」になったことを告知、その画面にて「了解」ボタンなどをクリックさせる、などの動作が必要か。
        ⇒ 不審に思われない為にもあった方が良いと思われるが、その時点で顧客を逃がしてしまうことはある程度覚悟しなければならない。
            ⇒ 「了解」ボタン作成が必要。カートでは、了解ボタンを押さないと購入手続きへ進めなくするなどの処理が必要。多分。
    4) いちいち個別に告知しない。
        ⇒ 全員に対して「ポイントの有効期限は、最終のご利用から2年間です」などと書いておいたらそれで事足りる?

・どのタイミングでポイントを「0」にUPDATEするか
    例えば、
    1) 最終購買日から○ヶ月経過した会員の全てに対してポイントを「0」にする処理を毎日0時にスケジュール(cron)で走らせる。強制。(上記SQL1)
    2) 「了解」ボタン押下でポイントを「0」にする。(上記SQL2)

・メールなどでの告知を行うか(メルマガを「受信しない」人にも配信する方がいいのか)
    ⇒スケジュール(cron)で有効期限切れの1ヶ月前などにメール配信。
        ・対象の会員へメール配信のプログラム作成。
        ・dtb_customerに告知しましたよフラグを持たせる。

辺りでしょうか。とても面倒です。

更には、不審に思われるかも知れないのでポイント履歴を参照可能なようにした方がいいのかなど、検討した方がいいでしょう。その場合はもっと面倒。
(その場合の処理としては、ポイント履歴テーブルを作って購入時及び管理画面からのポイント操作時にINSERTするだけですが。が、これまた新しい画面作成なり表示なりをしないといけない)


勿論、
最終購買日から○ヶ月経過した会員の全てに対してポイントを「0」にする処理を毎日0時にスケジュール(cron)で走らせる、告知一切なし、が最も楽です。
注意書きをちょっとしつこいめに書いておいたらいいだろ、問い合わせ対応も任せとけ、って豪気な方はそれでもOK。その場合は、上記SQL1 を 毎日0時にcronで走らせればそれでOKです。

EC-CUBEでcronを使う方法はこちら。↓
外部(Cronとか)からEC-CUBEで使ってるクラスを使う。


スポンサーサイト

自分店宛てへの受注メールの送信元を、お客様のアドレスにする

受注メールが自店宛てに送信されますが、デフォルトのままではお客様宛てメールをBCC送信されているだけなので、メーラーでそのメールを受け取る→メーラーの「返信」ボタンをクリック

などとすると自店宛てへの返信となってしまいます。それでいて受注メールにはメールアドレスなどの記載はないので、いちいち元メールの送信元をコピペしたり面倒です。実際やってるとイラっとします。
殆ど全く返信する必要がないのだったら別にそれでもいいのですが、実際そんなお店は少ないでしょう。

ということで、メールはBCC送信ではなく同じ内容のものをお客様宛て1通と自店宛て1通の計2通送信します。
自店向けへのメールは、送信先と送信元を逆にして送信してるだけです。
以下はそのサンプル。青字部分が追加分。

class/helper/SC_Helper_Mail.php
___________________________________________________________________
/* 受注完了メール送信 */
  function sfSendOrderMail($order_id, $template_id, $subject = "", $header = "", $footer = "", $send = true) {
      ・・・
      ・・・
      (省略)
      ・・・
      ・・・
      // $objSendMail->setItem('', $tosubject, $body, $from, $arrInfo['shop_name'], $from, $error, $error, $bcc);
      $objSendMail->setItem('', $tosubject, $body, $from, $arrInfo['shop_name'], $from, $error, $error);    //bcc不要にしただけ
      $objSendMail->setTo($arrOrder["order_email"], $arrOrder["order_name01"] . " ". $arrOrder["order_name02"] ." 様");

      // 送信フラグ:trueの場合は、送信する。
      if($send) {
          if ($objSendMail->sendMail()) {
              $this->sfSaveMailHistory($order_id, $template_id, $tosubject, $body);
          }
      }

//自店宛て(送信元:注文者)メール送信 ここから
      $objSendMail->setItem('', $tosubject, $body, $arrOrder["order_email"], $arrOrder["order_name01"] . " ". $arrOrder["order_name02"] ." 様", $arrOrder["order_email"], $error, $error);
      $objSendMail->setTo($from, $arrInfo['shop_name']);
      if($send) {
          if ($objSendMail->sendMail()) {
          }
      }
      //自店宛て メール送信ここまで

    return $objSendMail;
___________________________________________________________________

サンプルは、お客様宛てと自店宛てのメール内容は全く同じですが、必要によりお好みにより色々勝手に変えてみても勿論OK。自店宛てだけ何かしら表記するとか。
但し、お客様宛てと自店宛てで内容を変えた場合は、お客様宛てへのメール内容を正確に知る必要が別途出てくる場合があったりなかったりするので、その際はお客様宛てメールの自店向けBCC送信は復活させた方が吉。多分。


以上!


「お届け日」プルダウンに特定の”曜日”を表示させない

「お届け日」プルダウンに特定の”曜日”を表示させない

何かこればっかりやってる気がしますがきっと気のせいです。
今回はたまたまフォーラムで質問を見かけたので何となく。

ということで、「特定の日」じゃなくて「特定の曜日」です。毎週です。
下記は毎週「土曜」と「日曜」をお届け日プルダウンに表示しないサンプル。

ファイルは、

2.4.4系は data/class/pages/shopping/LC_Page_Shopping_Payment.php
(function:lfGetDateArray())
2.11系は data/class/helper/SC_Helper_Purchase.php
(function:getDateArray())

※functionの中身はどちらもほぼ同じ。

以下、青字部分が追加分。
___________________________________________________________________
    /**
    * お届け可能日のスタート値から, お届け日の配列を取得する.
    */
    function lfGetDateArray($start_day, $end_day) {
    //(または、function getDateArray($start_day, $end_day) { )
        $masterData = new SC_DB_MasterData();
        $arrWDAY = $masterData->getMasterData("mtb_wday");
        //お届け可能日のスタート値がセットされていれば
        if($start_day >= 1) {
        $now_time = time();
        $max_day = $start_day + $end_day;
        // 集計
          for ($i = $start_day; $i < $max_day; $i++) {
            // 基本時間から日数を追加していく
            $tmp_time = $now_time + ($i * 24 * 3600);
            list($y, $m, $d, $w) = explode(" ", date("Y m d w", $tmp_time));

            // 土曜と日曜を表示させない --------
            $flg_stop=false;
            switch(date("w", $tmp_time)) {
                case 0: case 6:
                //日曜と土曜
                    $flg_stop = true;
                      break;
                default:
            }
            // -----------------------------------

            if (!$flg_stop) {
                $val = sprintf("%04d/%02d/%02d(%s)", $y, $m, $d, $arrWDAY[$w]);
                $arrDate[$val] = $val;
            }
          }
        } else {
            $arrDate = false;
        }
      return $arrDate;
    }
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

プルダウンはあくまで「お届け日」なので一応注意。
曜日を変えたい場合は『case 0: case 6:』のところの数字を変えてください。0:日曜~6:土曜です。
曜日だけでなく祝日なんかにも対応しようと思ったら、それはそういうマスタを作るなり何なりするしかないです。祝日ってのは毎年決まっている日付じゃなくつまりは殆ど任意の日付扱いだから。
と言っても、その場合は、『「お届け日」プルダウンに”指定”の日付を表示させない』をそのまま使えば問題ないので、コレに足すなり引くなりしましょう。というよりアッチに足す感じですかね。
大体において、このブログ内の『「お届け日」プルダウンに~』の3記事を適当に組み合わせるなり応用するなりしたらどうにでもなる筈です。
ボチボチやりましょう。


以上!

<それでも俺用メモ>
「○○○は絶対反対」主義の蔓延をどうしたものかな・・それ確か原理主義っていうんだっけ?
俺界隈では最近すき焼きが大流行 ・・それでも肉
売れるネットショップ開業・運営 eコマース担当者・店長が身につけておくべき新・100の法則。・・正直高い。


「お届け日」プルダウンに”指定”の日付を表示させない

「お届け日」プルダウンに”指定”の日付を表示させない
ということで、「特定」じゃなくて「指定」です。
ソースにベタ書きはスマートとやらじゃないなどと言う人がいたりいなかったりするのでマスタ化してみました。はいはい。一理ありますよ。はいはい。
がしかし、それと大して変わらずお手軽の範疇ではあります。


1) テーブル作成
テーブル名: dtb_nodeliv_date
カラム:
nodeliv_id   integer  (primarykey)
nodeliv_date   date

create文:
CREATE TABLE dtb_nodeliv_date (
nodeliv_id integer NOT NULL,
nodeliv_date date
);
ALTER TABLE ONLY dtb_nodeliv_date
ADD CONSTRAINT nodeliv_id_primarykey PRIMARY KEY (nodeliv_id);

テーブルのデータは、
nodeliv_id | nodeliv_date
1 | 2011/12/31
2 | 2012/01/01

などと、表示させたくない日付を入れておく。行数不問。


2) ソース変更
2.4系は data/class/pages/shopping/LC_Page_Shopping_Payment.php の、
function:lfGetDelivDate(), lfGetDateArray()
2.11系は data/class/helper/SC_Helper_Purchase.php の、
function:getDelivDate(), getDateArray())

※2.4.4系、2.11系の上記functionの中身は殆ど同じ。
以下、青字部分が追加部分。
________________________________________

    /* お届け日一覧を取得する */
    function lfGetDelivDate() {
(2.11の場合)function getDelivDate() {

      ・・・
      ・・・
      ・・・

        break;
      default:
        //お届け日が設定されていない場合
        $start_day = "";
        break;
      }

      //NGお届け日取得
      $objQuery = new SC_Query();  //(2.4系の場合この行不要、2.11系の場合要)
      $arrNoDelivDate = $objQuery->select("nodeliv_date", "dtb_nodeliv_date");


      //お届け可能日のスタート値から、お届け日の配列を取得する
      $arrDelivDate = $this->lfGetDateArray($start_day, DELIV_DATE_END_MAX, $arrNoDelivDate);
      }
    return $arrDelivDate;
  }


    //お届け可能日のスタート値から、お届け日の配列を取得する
    function lfGetDateArray($start_day, $end_day, $arrNoDelivDate=null) {
(2.11の場合)function getDateArray($start_day, $end_day, $arrNoDelivDate=null) {

        ・・・
        ・・・
        ・・・

        // 集計
        for ($i = $start_day; $i < $max_day; $i++) {
          // 基本時間から日数を追加していく
          $tmp_time = $now_time + ($i * 24 * 3600);
          list($y, $m, $d, $w) = explode(" ", date("Y m d w", $tmp_time));

          $flg_stop = false;
          foreach ($arrNoDelivDate as $nodeliv) {
            list($ny, $nm, $nd) = explode('-', $nodeliv["nodeliv_date"]);
            if (($ny == $y)&&($nm == $m)&&($nd == $d)) {
              $flg_stop = true;
              break;
            }
          }


        if (!$flg_stop) {
          $val = sprintf("%04d/%02d/%02d(%s)", $y, $m, $d, $arrWDAY[$w]);
          $arrDate[$val] = $val;
        }

      }
    } else {
      $arrDate = false;
    }
    return $arrDate;
________________________________________

プルダウンはあくまで「お届け日」なので、運用の際は一応注意。

以上!


「お届け日」プルダウンに特定の日付を表示させない

「お届け日」プルダウンに特定の日付を表示させない。
店休日などで配送不可な日が時々あります、よね?
で、そういう日を指定して注文いただいたりしてしまうと色々面倒なので、「お届け日」プルダウンでその日を選べないようにしてしまいましょう。

ファイルは、
2.4.4系は data/class/pages/shopping/LC_Page_Shopping_Payment.php
(function:lfGetDateArray())
2.11系は data/class/helper/SC_Helper_Purchase.php
(function:getDateArray())
※2.4.4系、2.11系のfunctionの中身は全く同じ。
以下、青字部分が追加分。
___________________________________________________________________
    /**
    * お届け可能日のスタート値から, お届け日の配列を取得する.
    */
    function lfGetDateArray($start_day, $end_day) {
        $masterData = new SC_DB_MasterData();
        $arrWDAY = $masterData->getMasterData("mtb_wday");
        //お届け可能日のスタート値がセットされていれば
        if($start_day >= 1) {
        $now_time = time();
        $max_day = $start_day + $end_day;
        // 集計
        for ($i = $start_day; $i < $max_day; $i++) {
            // 基本時間から日数を追加していく
            $tmp_time = $now_time + ($i * 24 * 3600);
            list($y, $m, $d, $w) = explode(" ", date("Y m d w", $tmp_time));

            // 2011年8月24日,25日を表示させない --------
            $flg_stop=false;
            if (($y==2011)&&($m==8)) {
                if (($d==24)||($d==25)) {
                    $flg_stop=true;
                }
            }
            // -----------------------------------

            if (!$flg_stop) {
                $val = sprintf("%04d/%02d/%02d(%s)", $y, $m, $d, $arrWDAY[$w]);
                $arrDate[$val] = $val;
            }
        }
    } else {
        $arrDate = false;
    }
        return $arrDate;
    }
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

プルダウンはあくまで「お届け日」であって、店休日などとは違うので注意。一応。
まぁね、本当は、マスタ化するか定数追加して管理画面で設定出来るようにした方がいいんですけどね。
ですけれども、この方が明らかに手抜きでお手軽ではあります。コレをコピペで済ませたら2分で出来ます。

というかこれを適当に応用したらどうにでもなる筈です。きっと多分。


以上!


<本>
小さなチーム、大きな仕事


EC-CUBEでAjax

ということでajaxサンプル。何かと便利ですよ。
というかECCUBE関係なく色んなところで使えますし。
Ajaxやってみるかとちょっと調べてみたらあちこちに色んなこと書いてあってウンザリするけど実際やることはコレだけなんですけど。みたいな。

・このサンプルでやること
管理画面の「受注管理」→「ステータス管理」で注文番号のとこをクリックしたら受注詳細画面がポップアップで表示されますが、このポップアップの画面でajaxで「メモ」欄を入力・保存するという若干横着なことをします。
いやまぁこれはあくまでサンプルの為なので。

このサンプルではajax送信先でDB更新してるけど、送信先で何をしようと通信方法は一緒なので、送信先のサーバー側でphpなどでやることを変えれば画面のリロードや画面遷移なしで検索して検索結果を返すことも、メールを送信したりすることも問題なく可能です。
例えば、商品の「品切れ中」表示の横に「問い合わせ」ボタンを付けて「問い合わせ」ボタン押下でテキストボックスと送信ボタンを表示(これは普通にjavascriptで)させて→(ajax)→ メール送信 ということも、画面を更新することなく、とか。

・ポップアップの受注詳細画面(若干カスタマイズしてるので標準とは違うけど気にしない)
ajaxサンプル1


・入力
ajaxサンプル2

・保存
ajaxサンプル3


手順1)
data/Smarty/templates/default/admin/order/disp.tpl(のhtmlのbody部)に以下のhtmlを追記。
______________________________________________________________________
<textarea cols="120" rows="4" id="note" name="note" style="ime-mode:active;"><!--{$arrForm["note"].value}--></textarea>
<input type="button" value="保存" onclick="javascript:RequestByPost();" />
______________________________________________________________________

手順2)
data/Smarty/templates/default/admin/order/disp.tpl(のhtmlヘッダ部)に以下のjavascriptを追記。
______________________________________________________________________

<script type="text/javascript" language="JavaScript">
//<![CDATA[
function createXMLHttpRequest(){
  /* XMLHttpRequest オブジェクトを作成する */
    if(window.addEventListener){
        ;/* Firefox 用 */
        ;return new XMLHttpRequest();
    }else{
        /* IE 用 */
        return new ActiveXObject("Microsoft.XMLHTTP");
    }
}
function XMLHttpRequestByPost(){
  /* リクエストを送る */
    var request = createXMLHttpRequest();

    //POST送信
    request.open("POST", "/admin/order/send_message.php" , true);
    request.onreadystatechange = readyStateChangeHandler;
    request.setRequestHeader( "Content-Type" , "application/x-www-form-urlencoded");
    request.send("order_id=" + document.getElementById('order_id').value + "&note=" + document.getElementById('note').value);

    //ステータス( 読み込み中か完了か) が変更されたら、readyStateChangeHandler を実行
    function readyStateChangeHandler(){
        switch(request.readyState){
        case 4:
        //完了の場合、send_message.phpから送られたデータを表示
          if(request.status == 200){
              document.getElementById('result').innerHTML = request.responseText;
          } else {
              document.getElementById('result').innerHTML = "通信エラー";
          }
          break;
        default:
          document.getElementById('result').innerHTML = "保存中..";
          break;
        }
    }
}
function RequestByPost(){
    XMLHttpRequestByPost();
}
//]]<
</script>
______________________________________________________________________

手順3)
data/class/pages/admin/order/ 下に LC_Page_Admin_Send_Msg.phpを作成。

LC_Page_Admin_Send_Msg.php
______________________________________________________________________
<?php
class LC_Page_Admin_Send_Msg {
  function process() {
    $objQuery = new SC_Query();
    if ((isset($_POST['order_id']))&&($_POST['order_id'] != "")) {
        if ($_POST['order_id'] > 0) {
            $note = trim($_POST['note']);
            $order_id = trim($_POST['order_id']);
            $arrUpdate["note"] = $note;
            $where = "order_id = ?";
            $objQuery->update("dtb_order", $arrUpdate, $where, array($order_id));
            echo "保存しました。";
        }
    }
  exit;
  }
  function destroy() {
  }
}
?>
______________________________________________________________________

手順4)
/admin/order/下(dataディレクトリの下じゃない方)に send_message.phpを作成。

/admin/order/send_message.php
______________________________________________________________________
<?php

// {{{ requires
require_once("/var/www/hogehoge.com/httpdocs/admin/require.php"); // admin/require.phpのフルパス
require_once(CLASS_PATH . "pages/admin/order/LC_Page_Admin_Send_Msg.php");

$objPage = new LC_Page_Admin_Send_Msg();
register_shutdown_function(array($objPage, "destroy"));
$objPage->process();
?>
______________________________________________________________________


以上!

顧客に見せる用の注文番号(order_id)を作成。

注文番号(order_id)は完全連番なので、複数回購入されたお客さんに、その間の注文数がわかってしまいます。
注文の多寡に関わらず、(常識を超えて多いぐらいでないと)それがわかるというのは余り嬉しいことではないと思われます。

ということで、それでお客さんに見せる用の注文番号を作成しますよサンプル。

このサンプルの仕様としては、
年月日(8桁)+
ランダムなアルファベット(1桁)+
その日の最初の注文で6桁のランダムな数字を生成し、それにorder_idを足した数字(ゼロ埋め6桁)
計15桁とします。

手順 1)
テーブル作成。
テーブル名:dtb_order_random_id
列1: create_date  型:date  NOT NULL (PRIMARY KEY)
列2: start_order_id  型:integer  NOT NULL

手順 2)
テーブル dtb_order に列追加。
列名: custmer_order_id  型:varchar

手順 3)
data/class/helper/SC_Helper_DB.php に、
次のfunctionを作成します。一番下に追記とかで良いよ。
_____________________________________

 //客用注文No.を生成
  function getCustmerOrderId(&$objQuery, $order_id) {

      // 今日の開始値をテーブルdtb_order_random_idから取得
      $col = "start_order_id";
      $tbl = "dtb_order_random_id";
      $wh .= "to_char(create_date, 'YYYY-MM-DD')=?";
      $today = date("Y-m-d");
      $ret = $objQuery->select($col, $tbl, $wh, array($today));
      $order_random_id = $ret[0][$col];
      if ($order_random_id > 0) {
        // ある場合
      } else {
        // ない場合、ランダムな6桁の数字を生成してinsert
        $order_random_id = mt_rand(1, 999999);
        $sql = "INSERT into dtb_order_random_id(create_date, start_order_id)";
        $sql .= " VALUES(current_date, ?)";
        $objQuery->conn->query($sql, array($order_random_id));
      }

      // 客用注文No.作成 --- 年月日(8桁) + アルファベット(1桁) + (ランダム数字+order_id)(6桁)
      $custmer_order_id_tmp = intval($order_random_id) + intval($order_id);
      if ($custmer_order_id_tmp > 999999) {
        $custmer_order_id_tmp -= 999999;
      }
      $str_custmer_order_id_tmp = sprintf('%06d', $custmer_order_id_tmp);    //ゼロ埋め
      $today = date("Ymd");
      $alpbt = str_split("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
      $rand_keys = array_rand($alpbt, 1);

      $custmer_order_id = $today.$alpbt[$rand_keys].$str_custmer_order_id_tmp;
      return $custmer_order_id;
  }

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

手順 4)
data/class/pages/shopping/LC_Page_Shopping_Complete.php を編集。
function lfRegistOrder 内、
dtb_orderへのinsert直前に、次のコードを追記します。
_____________________________________

// 受注テーブルへ登録
  function lfRegistOrder($objQuery, $arrData, $objCampaignSess = null) {

      ・・・
      ・・・
      ・・・

      // 客用注文番号追加 start ---------
      $objDb = new SC_Helper_DB_Ex();
      $custmer_order_id = $objDb->getCustmerOrderId($objQuery, $order_id);
      $sqlval['custmer_order_id'] = $custmer_order_id;
      // ----------- 客用注文番号追加 end


      // INSERTの実行
      $objQuery->insert("dtb_order", $sqlval);

      ・・・
      ・・・

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

手順 5)
order_mail.tpl を編集。
_____________________________________

******************************************************************
 配送情報とご請求金額
******************************************************************

ご注文番号:<!--{$arrOrder.order_id}-->


ご注文番号:<!--{if $arrOrder.custmer_order_id}--><!--{$arrOrder.custmer_order_id}--><!--{else}--><!--{$arrOrder.order_id}--><!--{/if}-->

 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

以上!

・・ですが、

これでは本当のorder_idがメールではわからないので、必要であれば、自分(店)宛てにメールをもう1通作ってそれを店宛てにだけ送信しましょう。その中で、

注文番号:<!--{$arrOrder.order_id}-->
客用注文番号:<!--{if $arrOrder.custmer_order_id}--><!--{$arrOrder.custmer_order_id}--><!--{else}--><!--{$arrOrder.order_id}--><!--{/if}-->

とかやりましょう。
EC-CUBEのデフォルトのままでは客宛てメールをお店にBCC送信しているだけなので、「お客さんにはメールで見せたくないけど自分はメールで見たい」情報がある場合は、物理的にそれしか方法がないです。
(というより、それでなくても普通は客宛てと店宛ては分けた方がいいとは思う)

と、ここまで書いといて何なんですが、
上記のようにdtb_orderに列を追加する(order_idと別に持たせる)のではなく、アルファベットなんぞ入れないで数字のみにして注文番号(order_id)そのものをどうにかする、という方法もアリというかその方が一見楽そうではあります。

でもねえ、運用側の都合として、連番は連番でどっかに欲しいんですよねえ。必須ではないし明確なメリットという訳ではないけれども、あったらあったで番号だけで直感的に最近の注文かどうかわかったり短いから覚えやすかったり最近の注文数も何となく皆さんが把握出来ていたり、やんわりとイイことがあったりなかったりします。そしたら連番用列を追加しますか、ってことになったら手間としては結局のところ余り変わらなくなったりする訳です。
更に、ホンモノの方のorder_idをどうにかするということは、dtb_orderのキー項目をどうにかするということなので何かしら面倒なことになる可能性というか危険が危ないというか、そこをどうにかするということは通常のシステム屋的感覚、というよりあくまで俺的感覚ですが色んなテストケースでの総テストが必要と判断するレベルになってしまいます。こここれはメンド臭い。

だったら、ホンモノの方のorder_idは触らずに済むこっちの方が危険は少なそう、影響範囲も限られていて、何となく予期しないトラブルもなさそうだね、というこっちの方が良いように思います。これだと各画面・機能の通り一遍的なチェックで済みます。

運用に際しては、社内処理的にはこれまでの注文番号で良いけど、お客さんに知らせる番号がそれである以上、問い合わせ等の対応はこの番号で、となるので、管理画面で「顧客用注文番号」で検索とか出来るようにしておいた方が良いでしょうね。MYページの購入履歴のところも通常の注文番号表示なのでそこも忘れず修正。
何れにせよ色々メンド臭い訳ですが。


<本>
野村の流儀 - ノムさん本
<安>
BUFFALO 地デジチューナー

GMO-PG決済モジュール:カードエラー時のメッセージを設定

EC-CUBEペイメントとやらでGMO-PG決済モジュールをそのまま使ってると、クレジットカード番号エラーとか、クレジットカードが使えませんよエラーとかの画面に表示されるエラーメッセージが「ERRCODE:E01 ERRINFO:E01260010」みたいなことになってしまいます。

ということでこれを日本語にします。

本来なら、GMO配布のphpファイルを改編するか追加するか何かしてcredit.tplでメッセージを取得する時点で既にメッセージは日本語になってる、って方が良いんだけど、どこでどういう風にエラーメッセージを取得してセットしてるか追いかけてたら頭痛くなってきたのでもうメンド臭いんでこのcredit.tplで何とかします。
というか実を言うとGMO推奨でもこのcredit.tplを触って何とかしろ、と書いてあります。出来ればphpファイルは触って欲しくないんだろうね。まぁ当たり前。

・対象ファイル
data/downloads/module/mdl_pg_mulpay/templates/credit.tpl

以下原文
________________________________________________________________
(83行目ぐらい)
    <!--{if $arrErr.gmo_request}-->
      <table summary="お支払い方法">
        <tr>
        <td class="lefttd">
        <p class="attention">エラーが発生しました:<!--{$arrErr.gmo_request|escape}--></p>
        <!--{if $arrErr.gmo_request == 'E01-E01230009'}-->
          <p class="attention">カードの最大登録数5件を超えています。新しいカード情報を登録する場合には、登録済みのカード情報を呼び出して、<br/>削除してください。</p>
        <!--{/if}-->
        </td>
        </tr>
      </table>
    <!--{/if}-->
________________________________________________________________

以下修正後
________________________________________________________________
  <!--{if $arrErr.gmo_request}-->
    <!--{assign var=err_cd value=$arrErr.gmo_request|trim}-->
    <!--{if $err_cd == 'ERRCODE:E01 ERRINFO:E01230009'}-->
      <!--{assign var=err_msg value="カードの最大登録数5件を超えています。新しいカード情報を登録する場合には、登録済みのカード情報を呼び出して、<br/>削除してください。"}-->
    <!--{elseif $err_cd == 'ERRCODE:E01 ERRINFO:E01170011'}-->
      <!--{assign var=err_msg value="カード番号が10桁~16桁の範囲ではありません。"}-->
    <!--{elseif $err_cd == 'ERRCODE:E01 ERRINFO:E01260010'}-->
      <!--{assign var=err_msg value="指定された支払方法はご利用できません。"}-->
    <!--{elseif $err_cd == 'ERRCODE:G02 ERRINFO:42G020000'}-->
      <!--{assign var=err_msg value="カード残高が不足しているため、決済を完了する事が出来ませんでした。"}-->
    <!--{elseif ・・・
        ・・・
        ・・・
    <!--{else}-->
      <!--{assign var=err_msg value="予期しないエラーが発生しました。<br>時間を置いて再度お試しいただくか、お問い合わせください。"}-->
    <!--{/if}-->

  <table summary="お支払い方法">
    <tr>
    <td class="lefttd">
      <p class="attention">エラーが発生しました: <!--{$err_msg}--></p>
    </td>
    </tr>
  </table>
  <!--{/if}-->
________________________________________________________________

エラーコードとエラー内容(メッセージ)は、GMOサイト管理画面 の「ドキュメント」タブ → エラーコード表 でDL出来ます。


<俺用>
CSWブログ ・・民間宇宙開発企業?の人のブログ
最高のステーキ ・・やっぱり肉!
Oracle XE ・・oracle 10g Express Edition

Smartyはテンプレートエンジンだからロジックを書くな厨

何でこんなブログを書いてるのかというと、Q&Aサイトで質問に対して説教で答える人とか、質問者の不備を挙げては質問の意味がわからない、○×がわかってない、△■から勉強しろとか、正直申し上げて何しにわざわざそんなとこに書き込んでるのか意味がわからないというか、答える気ないんなら出てくるなというかですね。そういうのを目にしてイラっとする事が時々あって、ほな俺も何か書いてみるか、と思ったからなんですね。いやまぁ俺のなんか大したことは書いてないけど。
説教してる本人は親切のつもりか知らんけどそんなもんはっきり言って迷惑な訳です。
反対に、とっても親切な人もいるもので、質問に不備があっても多分こういうことではないかと予測して、違ってたらごめんねって感じでそのものズバリに答えてたり、公開してたりしてくれてる人もいます。

そらね、理屈は大事ですけど、でも、絶対に「答え」より先に知らないといけないものではなくて、それは後付けでも良いんですよ。むしろ答えを知ってる状態で理屈を追うと理解のスピードが違ったりします。既に動いてる具体例があるから、スッと入ってきたりします。その「答え」を色々いじくってる内に理解したりすることもあります。
面倒だったり時間がなかったりしたら理屈をすっ飛ばして答えだけどっかからコピペしてきてようわからんけど動いたからOK、みたいな時があるのも否定しないけど、それにしたって、いずれは壁にぶち当たって、いずれは理解しなきゃならない。殆どの場合。
みんながそんな感じで、人の時間を短縮してあげる気でいたら、この世界、もっと早く進歩してるんだろうなって気しますわ。
あ、俺は、この世界って進歩のスピード目茶目茶遅いなって感じてます。遅いっていうか、進歩してるのかどうかすら怪しい。
言語やインターフェイスやフレームワークや色んなツールやら何やら色んなモノが変わっていったり新しいモノが出てきても末端がやってることは15年前と同じ。どこも、一つ道を踏み外したら後は人月計算でマンパワー使ってゴリゴリ徹夜作業で挽回、みたいな。そういうとこは挽回しないけど。まー何も変わっとらんなと思う訳です。いや「何も」ってことはないか。非常にゆっくりだけど一応進化はしてる、とでも言った方がいいのかな。

で、EC-CUBE関係で検索してるとよく見かけるのが「SmartyはテンプレートエンジンなんだからSmartyにロジックを書くな厨」。長。

うむ。そんなことは百も承知です。それしか言わないんなら黙っててください。知ってますから。知ってて聞いてるんですから。いや俺は聞いたことないけど。見てると、ね。
どうしても言いたいんなら、或いは親切心なら、解答を書いた上で「テンプレートエンジンだから本来は~」などとさらっと添えてあげればいい。
そんな原理原則で説教だけされてもね。こっちだって色々都合があるんだよ。
サードパーティ提供で改編不可のロジック(.php)があって、あとはSmarty側で何とかしないといけない場面とかね。
よくあるところでは、Smartyで対応した方が遥かに工数が少ない場面なんか何ぼでもあります。納期や工数の為に何をどれだけ妥協出来るかって話なのに、原理原則は何があっても絶対に曲げたら駄目だみたいな頭の固い輩がたまにいますよね。
あと、多人数でやってるプロジェクトならともかく、1人や2人で自分達だけのショップの為だけにやってるようなのにそんな原理原則なんかどーでもいいんですわ、とか、そもそもデザイナーとPGと店の人は同一人物で別の誰かにやっていただく予定も想定もありません、とか。
大体、Smartyだってそういうことの為に色々出来るようになっている訳で、反対にそれが出来ないテンプレートエンジンだったらつまりそれはそういう時に対応出来ないってことであって、そんなもん誰も使わんよ。
まーそれを言ったらSmarty自体俺は要らないんだけども。だって既にphpって埋め込みタグの言(ry

つーかそれ以前に、こんなテンプレート、純粋なデザイナーが使いこなすのって多分無理ですから。ごく一部にやる人もいるかも知れんけど。
多分大体が、デザイン屋にhtmlとcssと場合によってはjsも含めてデザインだけさせて、後からテンプレートタグを埋め込むのはPGとかの仕事になりますよね。そんなシロモノをデザイン部分とロジック部分とに無理クリ分ける意味もようわからん。

まーあんまりぐちゃぐちゃになるのもどうかとは思うけど、多少は別にいいんでないの。
まぁね、jspが最初に出てきた頃とか、htmlに埋め込みタグってのがイマイチ浸透してない時代は、jsp内でDB接続してそのままDBから取得しながらoutputしながらループさせて云々みたいなクソみたいなのも結構見かけたけどね。つーか最近でもたまに見かけるけどね。さすがにソレはない。苦笑

ポイント計算方法の変更。(商品ごと⇒全商品の合計に対して)

商品ごとにポイントを加算するのではなく、
全商品の合計に対してポイントとしたい場合サンプル。

例えば、ポイント計算切り上げ(1%)の場合、
850円(9ポイント) × 2 ⇒ 18ポイント
ではなく、
850円 × 2 = 1700円 ⇒ 17ポイント
としたい!場合。

ちなみに、商品ごと計算ではないので、ここではキャンペーンとか無視してます。

1)準備
・そういう計算にしたらしたで商品に表記してるポイント表記も直さないといけないとか、その他諸々で色々問題が発生するかも知れないので一応いつでも元に戻せるようにしておく。
→ 'POINT_RULE_ORG'という定数(パラメータ)を追加。
・商品ごとのレートではないので全商品(合計)に対してのレートを新たに設定する。
→ 'DEFAULT_POINT_RATE'という定数(パラメータ)を追加。

定数の追加方法は、定数(パラメータ)を追加でも参考にしてください。
例)
 1-1) mtb_constants に行を追加。

insert into mtb_constants
values('POINT_RULE_ORG', '0', 530, 'ポイント加算方法 0:商品ごと 1:商品合計に対して');
insert into mtb_constants
values('DEFAULT_POINT_RATE', '1', 531, 'ポイントのレート(%)');

 1-2) 上記追加後、管理画面の「システム設定」 → 「パラメータ設定」
管理画面の「システム設定」 → 「パラメータ設定」

この画面で、
POINT_RULE_ORG:「0」(というかそう作成した)を「1」にする
(※この値を「0」にすると今まで通り、「1」にすると合計金額に対して、の計算方法となる)
「この内容で登録」する押下
DEFAULT_POINT_RATE:全商品の合計に対して何%をポイントとするか入力。
(※ここでは1%)
「この内容で登録」する押下。(※mtb_constantsに行を追加後は、その後内容を変更しようがしまいが1度は押下しておく)

2)ソースコード編集
編集するファイルは2つ。
・data/class/SC_CartSession.php
・data/class/helper/SC_Helper_DB.php

 2-1) SC_CartSession.php の、

  // 全商品の合計ポイント
  function getAllProductsPoint() {
    ・・・
    ・・・
    return $total;
  }

の下辺り(どこでも良い)に、下記のfunctionを追加。商品を合計してレートを掛けて100で割ってるだけ。
コピペで多分問題ないよ。た、多分。

SC_CartSession.php
_____________________________________________________________________________

  // 全商品合計に対するポイント
  function getAllProductsPoint_org() {

    $pt = 0;    //ポイント計
    $ans = 0;    //ポイント計 切捨など処理後
    $price_total = 0;    //商品の合計金額
    $max = $this->getMax();
    for($i = 0; $i <= $max; $i++) {
      $price = $_SESSION[$this->key][$i]['price'];
      $quantity = $_SESSION[$this->key][$i]['quantity'];
      $price_total += ($price * $quantity);
    }
    $pt = $price_total * DEFAULT_POINT_RATE / 100;
    switch(POINT_RULE) {
    case 1:
    // 四捨五入
      $ans = round($pt);
      break;
    case 2:
    // 切り捨て
      $ans = floor($pt);
      break;
    case 3:
    // 切り上げ
      $ans = ceil($pt);
      break;
    default:
    // デフォルト:切り上げ
      $ans = ceil($pt);
      break;
    }
    return $ans;
  }
_____________________________________________________________________________


 2-2) SC_Helper_DB.php の、function sfTotalCart() 内を下記の通り編集。
POINT_RULE_ORG が「0」の場合は従来通りで、「0」以外の場合は上記で作ったfunctionを使って計算しましょう、というだけ。
_____________________________________________________________________________
青字は編集というか追加箇所)
  function sfTotalCart(&$objPage, $objCartSess, $arrInfo) {

    ・・・
    ・・・
    ・・・
    // 全商品合計ポイント
    if (USE_POINT === true) {
      if (POINT_RULE_ORG == 0) {
        $objPage->tpl_total_point = $objCartSess->getAllProductsPoint();
      } else {
        $objPage->tpl_total_point = $objCartSess->getAllProductsPoint_org();
      }

    }

    return $objPage;
  }
_____________________________________________________________________________



確認画面


以上!

<俺用リンク>
ジョナサン・ケイナーの星占い ・・・ 信じなくても結構面白い。
阪神・淡路大震災5日後収録(10日後放送)のパペポTV ・・・ 上岡、鶴瓶。
義援金まとめ ・・・ 一覧。

Appendix

プロフィール

modezo

Author:modezo
モデゾー

思いたって書き始めたのが随分出来てからなので実は書くことがあんまりない。

全記事表示リンク

全ての記事を表示する

 

newsing

にほんブログ村 IT技術ブログ 自社サイト運用へ
にほんブログ村

ブランド和牛一覧
近江牛ステーキ・しゃぶしゃぶ
SEOTOOLS999|相互リンクSEO-P-Link ver3.5
匹夫の勇|相互リンクSEO-P-Link ver3.5
頓珍漢|相互リンクSEO-P-Link ver3.5

Googleページランク表示ツール PagerankExplore

あわせて読みたい

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。