受注管理

実際の業務画面の大きさで書いたものです。受注をサーバから取り、検索して、状態で絞り込み、列で並べ替え、行を押すと明細が開き、数量を直して保存すると通知が出て、しばらくすると消えます。

画面に見えるものは全部デザイナのもの

デザイナが書いた index.html を先に読むと分かりますが、そこには LPScript のための印が一つも入っていません。id と class は、CSS を当てるために元から書かれるものです。

LPScript の側は、その見本を複製して値を入れます。

Screen >> rowOf: o = (
  r := Html clone: '#lines tr' fill: {
    '.c-id'       -> o id.
    '.c-customer' -> o customer.
    '.c-total'    -> (self yen: o total).
    '.c-status .badge' -> o status label }.
  (r on: #click send: #select: with: o id) key: o id ).

デザイナが列を足しても、class 名が残っていれば、こちらは何も直しません。逆に class 名が変われば、組み立てが止まります。黙って値がどこにも入らない、ということは起きません。

状態は文字列ではない

未処理・処理中・完了は「このどれか」です。文字列で持つと、綴りの間違いも、比較の書き忘れも、実行するまで分かりません。そこで種類ごとにクラスを書き、プロトコルで「答えるべきもの」を決めます。

Protocol subclass: #Status requires: (#label #badge #next).

Object subclass: #Pending protocols: (Status).
Pending >> label = '未処理'.
Pending >> badge = 'b-new'.
Pending >> next  = Working new as: Status.

'未処理' と書いてあるのはここだけです。絞り込みの札の文字も、JSON から読むときの突き合わせも、CSS の class 名も、次の状態への遷移も、この三行から出てきます。種類を足して badge を書き忘れれば、コンパイラが止めます。

待たない

サーバへの要求は投げて、返事はメッセージで受け取ります。

Screen >> load = (
  (Http get: 'orders.json') then: [:r | me ref tell loaded: r].
  self ).

ハンドラはすぐ終わるので、通信の間も画面は操作に答えます。要求は失敗しません。線が立たなければ status 0 の応答が返るので、受け止める場所は一つで済みます。

金額

qty は Int、price は Decimal です。金額は掛けてから円未満を切り捨てます。どこで丸めるかを書かせるのが Decimal の役目です。

Order >> total = (qty asDecimal * price) truncatedTo: 0.

JSON から読むときも桁は落ちません。数値は届いた文字のまま運ばれ、asDecimal と言われたときに初めて数になります。