Rich Lab. Blog

「まつらリッチ研究所」の研究の一環で、はてなブログ上にブログを公開。でもなぜか買い物カゴが……。はてブはそんな機能あったっけ?

値引きをプログラミングする(売り方も作品の一部だ)

POSIX原理主義者割引き」はじめました

f:id:richmikan:20150719144455j:plain

書籍「すべてのUNIXで20年動くプログラムはどう書くべきか」を著者の通販サイト(ココのサイト)で購入されるお客様に、ささやかながら値引きを致します。

とはいっても商業本を値引きすることはできない決まりなので、元になった同人誌をセットで購入される方に、その同人誌の方を400円値引きします。

他の書店には絶対マネできないこの企画。是非下のボタンを2つともポチしてください。(Safariの方は本店でポチ!

商業版カゴ入れボタン同人版カゴ入れボタン

冊入っています

冊入っています

「分割金利手数料はすべて負担」はジャパネットたかたの『作品』

以前、あのジャパネットの高田社長が「ショッピングはエンターテインメントです」と言っていた。「分割金利手数料は店が負担」の第一人者だし、ハプニング覚悟で生放送を止めないし、高田社長は経営を引退しても未だに出演は続けている。

それらはまさに、エンターテインメントだという前提があるからであって、ジャパネットたかたはメーカーが作った作品(=製品)を売りながら、自分達が考案したショウ(=実演)や値引き(=分割金利手数料負担然り)という作品を売っているのだ。

つまり「値引き」とは店の作品の一つである。作品であるということは、値引きの仕方にもオリジナリティーがなくてはならない。客はオリジナリティーを感じるから、例え値引き額がさほどでなくても、その店を選ぶ。(実際、ジャパネットの価格も価格.comで見つかる最安店には敵わないことが多い。それでも売れる)

ネットショップ店主が独自の値引き企画を創設するのは難しいという現実

そうすると「なるほど、独自の値引き制度を考案するのも一つの手なのか!よし、やろう」と思う。ところが、多くのネットショップ店主にとってはそれが難しい。なぜなら、ネットショップ上で値引きを実施したければ、ショッピングカートプログラムにやらせなければならない。でも店主は基本的にプログラマーではないので、ショッピングカートで値引き販売をしたければ既製のものから選ぶしかない。結局それは店独自の「作品」ではない。

WordPressといったCMSなど、ページデザイン(店の内装)の制作にはある程度店独自にオリジナリティーを表現させるプログラムはあるのに、なぜ値引き制度という分野ではオリジナリティーを表現させるプログラムがないのか!

値引きルールをプログラミングで表現する

このような問題点に気付いたので私は自前のショッピングカートプログラムに値引き機能を実装してみた。もちろん、既製の値引き機能を作るのが目的ではない。導入する店主が独自の値引き企画を導入できる仕組みだ。

細かい話はヌキにして、どうやったかだけを記そうと思う。ちなみに、うちの自作ショッピングカートはシェルスクリプトで書かれている。

1) 買い物明細生成プログラム本体にフックを置く

値引き機能を入れ込む対象となるのは、買い物明細を生成するプログラムである。しかし、これを下手いじるとシステムそのものが復旧不可能なほどに壊れてしまうという問題がある。

そこで、開発者と店主がいじるべき領域の違いを明確化すべく、店主がいじるべきプログラムファイルは外出しし("$Homedir/CONFIG"というディレクトリーの中に"DISCOUNT_RULES.SHLIB"という名前で置くこととし)、存在すればインクルード(".":sourceコマンド)するようにした。→冒頭部分

######################################################################
# 初期設定
######################################################################

# --- このシステム(CART)のホームディレクトリー -----------------------
Homedir="$(d=${0%/*}/; [ "_$d" = "_$0/" ] && d='./'; cd "$d.."; pwd)"

# --- その他初期ディレクトリー等定義 ---------------------------------
[ -f $Homedir/CONFIG/DISCOUNT_RULES.SHLIB ] && { # 値引きルールライブラリー登録
  . $Homedir/CONFIG/DISCOUNT_RULES.SHLIB         # (存在すれば)
}
   :
   :
   :

# --- 小計を求め、レシートファイルに記入 -----------------------------
cat $Tmp-in_the_cart                                                            |
# 1:商品ID 2:カゴ入り数量                                                       #
join -1 1 -2 1 -o 2.1,1.2,1.3,1.4,1.5,1.6,1.7,2.2 $Tmp-productmaster -          |
# 1:商品ID 2:商品名(mojihameエンコ) 3:単価(+税表記含) 4:発売日 5:重さ厚さ       #
# 6:在庫情報体 7:URL 8:カゴ入り数量                                             #
if PATH='' type DISCOUNT_BEFORE_CALCULATING_TAX >/dev/null 2>&1; then           # 税金計算前の値引き
  DISCOUNT_BEFORE_CALCULATING_TAX                                               # (ルールが設定されている場合)
else                                                                            #
  cat                                                                           #
fi                                                                              |
awk '{print $1,$2,$7,$3,$8}'                                                    |
# 1:商品ID 2:商品名(mojihameエンコード) 3:URL 4:単価(+税表記含) 5:カゴ入り数量  #
awk 'BEGIN          {sotozei_target_amt = 0;                          }         #
     $4~/\+[Tt]$/   {zeinuki_unitprice = substr($4,1,length($4)-2);             #
                     sotozei_target_amt += zeinuki_unitprice*$5;                #
                     print $1,$2,$3,zeinuki_unitprice,$5,zeinuki_unitprice*$5;} #
     $4~/^-?[0-9]+$/{print $0,$4*$5;                                  }         #
     END            {tax = int(sotozei_target_amt*'"$TR_TAX_RATE"');            #
                     print "TAX 消費税(税別商品分) -", tax, 1, tax;}'           > $Tmp-reciept
# 1:商品ID 2:商品名(mojihameエンコード) 3:URL 4:単価(税抜) 5:カゴ入り数量 6:小計

上記のコードの後半部分は、明細テキストデータを生成している箇所だ。joinやawkをパイプで繋ぐといういかにもシェルスクリプトらしいコードである。

このコードの中盤に"DISCOUNT_BEFORE_CALCULATING_TAX"という謎のコマンドが出てくる。これが(消費税計算前に)値引きを行うためのプログラム(後述)なのだが、じつは外部コマンドではなくてシェル関数である。typeコマンドによってその存在を確かめてから、存在すれば実行し(パイプで通し)、存在しなければcatコマンドで到来データをそのまま通過させるというロジックだ。

if文ごとパイプに通せるのがいかにもシェルスクリプトでしょ?

2) 店主がいじる値引き実行用のシェル関数

明細生成プログラム本体はフックを入れただけなので、値引きを実行するプログラム本体は別にある。店主は、独自に考案した値引き企画を、この部分でシェルスクリプトという表現手段を用いて表現する。

店主は、値引きを企画したいのであれば $Homedir/CONFIG/DISCOUNT_RULES.SHLIB という名のファイルを用意し、DISCOUNT_BEFORE_CALCULATING_TAXというシェル関数を書く。

今回は、商業本(商品ID=pfb)と同人本(商品ID=ssr2)を同時購入した筋金入りのPOSIX原理主義者に向けた割り引きだが、それをプログラミングしたものが次のシェルスクリプトだ。

######################################################################
# 商品確認後、税計算前段階での値引き
######################################################################
#
# [使用方法]
# * 使いたい場合は、このシェル関数の名前を
#   "DISCOUNT_BEFORE_CALCULATING_TAX"
#   にして、下記の入出力の規則に則ってプログラムを書く。
# [入力]
# * 標準入力から次のデータが送られてくる
#   1:商品ID
#   2:商品名(mojihameエスケープ)
#   3:単価(外税商品は末尾に"+t"と書かれている)
#   4:発売日
#   5:重さ厚さ情報
#   6:在庫情報体(電子商品は"*")
#   7:商品URL(なければ"-")
#   8:カゴ入り数量
# [出力]
# * 標準出力に上記情報をそのまま通過させるのを忘れずに!!!!!
# * それに加えて、必要に応じて次の列を出力する。
#     1:値引ID("^DISC.[A-Za-z0-9_.-]*$"形式に合致すること。例、"DISC.campain1")
#     2:値引理由の名称(mojihameエスケープ)
#     3:値引単価
#       - 負値にすること!そうしなければ割増しになってしまう
#       - 外税商品の値引きをする場合は数字の直後に"+t"を付けると税も値引かれる
#     4:"-"(ダミー列につき無視されるので何でもよい)
#     5:"-"(ダミー列につき無視されるので何でもよい)
#     6:"-"(ダミー列につき無視されるので何でもよい)
#     7:値引理由を説明しているページがあればそのURL(無ければ"-")
#     8:適用数(第4列の名目を複数口適用したい場合はここを2以上にする)
#
DISCOUNT_BEFORE_CALCULATING_TAX() {

  awk '
  {
    # カゴに入っている商品IDとその単価・数量の登録をしながら出力
    pri[$1] = $3;
    qty[$1] = $8;
    print;
  }
  END {

    # 「POSIX原理主義者」割り引き
    # ・商品ID[ssr2]が存在する場合、商品ID[pfb]1冊につき400円値引く。
    # ・ただし値引き額の最大は、商品ID[ssr2]の小計である。
    if (("ssr2" in qty) && ("pfb" in qty)) {
      p = -400      ;
      q = qty["pfb"];
      if (p*q*(-1) > pri["ssr2"]*qty["ssr2"]) {
        p = pri["ssr2"]*qty["ssr2"]*(-1);
        q = 1;
      }
      print "DISC.POSIX POSIX原理主義本同時購入よる同人版値引き",p,"- - - -",q;
    }

  }
  '
}

実体はAWKのコードである。それがシェル関数でラッピングされているに過ぎない。

標準入力から、冒頭のコメントにある通りの仕様でカゴに入っている商品明細データが渡ってくるのでそれを標準出力へと素通りさせつつ、そのうしろに今回の値引きルールに基づく値引き項目を追加して標準出力へ送るのである。出力時のデータフォーマットも、冒頭に記されたコメントに従う。

値引きのためのプログラミング学習も、デザインのためのHTML学習と同程度にしたい

上記の解説はプログラミングに慣れた人にとってはさほど難しい話ではない。では、そうではない純粋な商売人にはどうだろうか?

確かに上記のようにして値引き実施コードを本体から切り離したものの、きちんと書かなければ本体も動かなくなるわけで完全に安全になったとは到底言えない。

しかし、ネットショップの内装(デザイン)を弄るためにHTMLやCMSを覚えことのがある程度受け入れられているのだから、その程度にまで敷居を下げさえすればよいと思うし、またできるはずだ。

それができなければ、個人のネットショップなど大手に潰されてしまう。

 

 

 

 

←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。