受注管理
実際の業務画面の大きさで書いたものです。受注をサーバから取り、検索して、状態で絞り込み、列で並べ替え、行を押すと明細が開き、数量を直して保存すると通知が出て、しばらくすると消えます。
画面に見えるものは全部デザイナのもの
デザイナが書いた 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 と言われたときに初めて数になります。