八丈島のホテルで、運用費用0円の伝票システムアプリ作って、業務改善した話。八丈島のホテルで、運用費用0円の伝票システムアプリ作って、業務改善した話。Kotlin読了目安:11分QIitaと同じ投稿です!Qiitaで読みたいという方はこちらこのたび東京都八丈島のホテル、リードパーク&リゾート八丈島で伝票システムアプリを作らせてもらいました!このシステムアプリの全機能はブログの記事で動画を交えて説明しています。今回自分がこんな貴重な機会を得られ、最後まで作ることができたのは、寛容で柔軟なホテル支配人・レストランリーダー・スタッフの皆様のお陰だと本当に思います。最初は遅延もあったり、レシート2枚出てきたりしてましたが、毎日使用後に多くのフィードバックを得られたので開発がとても捗りました。「楽しい!」「今までで1番使いやすい」などの声は本当に嬉しいです:laughing:Firebase(Google)さんありがとうFirebaseとGoogleさん!!!お陰でサーバーレス・運用費0円で開発できました。レシート印刷というものです。Databaseでつくりました。自分は1998年生まれで、神戸大学の経済学部に通っていて現在は休学中です。チュートリアル本から学び始めて今に至ります。なにか作って公開しようとおもいます。この後は東京に行ってどこかで働きたいと思ってます!(ご縁があればよろしくお願いします:raising_hand_tone1:)このアプリを作ることになった経緯もともとこのホテルのレストランで住み込みバイトで働いていて、空いた時間に個人開発でアプリを作ろうと思ってました。ある大きいレストランです。ここで働いているうちに色々な改善点があるなと思うようになってきました。流れと、伝票計算の処理です。レストランの業務は開店・閉店作業を除くと主に、以下の作業です。ドリンクの追加注文を受けるたび、作業中断でドリンクを作り、持っていく。この1、3のドリンク作業がネックでした。従来はドリンクの注文の度、このように、1人のスタッフが一連の作業を全て行っていました。夕食の時間帯は3つあって(18時~/18時30分~/19時~)、それぞれの時間帯で約20~50名ほどが一気に来られます。スタッフは1席ごとの注文で1往復するので、最初のドリンクを早く捌かないとその後の全ての作業が遅れてしまいます。追加注文の際も、作業が中断されるので効率が落ちてしまいます。お客が全員帰ると、各伝票に各ドリンクの単価を記入して、電卓で合計を計算、記入していました。7)をポケットに入れ、バーカウンターに通信用の端末1台と、サーマルプリンター1台を置いています。注文を受けるスタッフは、バーカウンターに行く必要はなく、注文入力後、次の席に行ってまた注文を受けられます。バーカウンターのスタッフは次々と印刷されるレシートを見て、ドリンクを作り、お盆にレシートと一緒にドリンクを置いていきます。手の空いているスタッフが、そのお盆を持ち、レシートに記されている席まで運びます。(レシートはどんどん重ねて挟んでいく。(結局導入には至らなかったそうです。TSP650||?スター精密は安心できるし、SDKもしっかりしていて、尚且つ安価なのが決めてでした。(4万円弱)このモデルはBluetooth通信に対応していて、印刷速度も1番早かったのでこれに決めました。Android?もともとFire端末があり、自分もAndridを学び始めたばっかだったから。OSは、独自といってますがほぼAndroid。)この偶然はラッキーでした。Kotlin?自分が学び始めたのがKotlinからだったから。(Javaと100%相互互換なので結果的にJavaも段々わかってきた。Firebase?最初はAWSかAzureと思っていたのですが、Firebaseは無料枠(しかも大容量)があり、それにDBの性能が最高でこれだけで十分だったからです。Azureにも感謝です。👇100名ほどのディナー1日で、この容量なので、まだまだまだ余裕があります。RealtimeDB?これは、FireStoreと悩んだのですが結局RealtimeDBにしました。Key-Valueなので、高速。FireStoreの特徴の強力なクエリは必要なかった。ベータ版なのでちょっと気が引ける。お客130人前後の注文情報なんて500Bぐらいで済むので、遅延とかはそこまで変わらないと思います。それに最近知ったのですが、FireStoreの方はGoogleのインフラをフル活用していて、今後GoogleはFirestore推しでいくらしいです。β版というのが気になりました。次の個人開発からはFirestoreを使います。さんのご指摘で、見落としに気付きました。使いましょう!課題解決ここからは、開発の過程でつまづいた所、その解決策を書いていきます。レシート1枚で全ての情報を表す。分業化するにあたって、注文を受ける人・ドリンクを作る人・運ぶ人はレシート1枚を通して情報伝達を行う必要があります。各ドリンク(商品)の単価お部屋番号(会計は部屋付けなので)以上の情報を1枚のレシートに入れなければなりません。最初はStarPrntのSDKを使えば、なんか良い感じに自動で割り振ってくれると思ってました(希望的観測)。実際は自分でテンプレートを作ったり、行数・フォントサイズを調整する必要がありました。これはこれでめっちゃ楽しかったです。普段のレシートに目が行くようになって、「あ~これ手抜いてるな」とか「すげぇ!どうやって!?」みたいに思うところが増えました。コードを貼るとめちゃ長くなるので、別記事でレシートの作り方はまとめます。言うと、縦横を揃えるためにすべての文字を全角にして、計算して空白を適切な数入れたり、1行に収められるようにしたりしました。👇(半角のサイズは全角の半分でないため、混ざっているとややこしい。超はしょって、試行錯誤の末こうすることで解決しました。以下の点に気を付けました。注文ごとをブロックで分け、どの注文を作れば良いのか、わかるようにした。(常に1番下のブロックのドリンクを作る)これで、お客は何を頼んで合計は何円かわかるし、ドリンクを作る人も何をどのように作るのか、運ぶ人もどこに運ぶのかを一目でわかるようになりました!注文ごとをブロックで分けるにはDBの設計を見直す必要がありました。DB設計で気をつけたことは後述しますが、これは柔軟なNoSQLモデルだからこそ簡単にできたのだと思います。プリンターの排他制御これはめちゃくちゃ悩みました。排他制御自体を知らなかったので探そうにもGoogleは教えてくれず、、、だったのですがMENTAというサービスでメンターの方に相談するとすぐに解決しました。@Syncronizedを入力するだけで排他制御が実装できます。初期化の処理を行うようにします。RealtimeDBでは、リレイショナルなモデルではなく、データをJSONツリー型で保持するNoSQLモデルです。自分はリレイショナルなDBをほとんど触ったことがなかったので、逆に変な違和感とかはなかったです。余計なデータまで読み込まないように、深くネストしない効率よく必要なデータを見つけるための、平坦化(非正規化)です。このアプリでは、DB設計を考えるにあたって各注文ごとをブロックで分ける(理由は上記)簡単にレシート印刷できるようにするという事を考えながら設計し、以下のようにしました👇!(11番テーブルの注文のみ)RealtimeDBでは、最大34回ネストできるのですが、ここでは5回に抑えることができました。11)と紐づけることで、注文2回目以降は、テーブル番号入力後、すぐにメニュー画面へ遷移でき、途中でデータの削除や数量変更などもできます。上の"Checker"ノードを作ることで、、効率的にレシートを印刷できます。色々なクラスからレシートを印刷する必要があるのですが(注文履歴変更後や、確認用など)、それも以下のコードで実装できます。//実際のコードでは、この値をintentで渡している。check時々レシートが2枚印刷される問題は、この実装で解決しました。直感的なUI前に導入しようとしていた伝票システムは、全体的に単色で、メニューの選択画面が文字のリストで、とても見にくかったとのことでした。自分は極力文字を少なく・画像やベクター図を多く、見やすい色やフォントサイズを心がけました。1つの画面で全ての操作を終えるのはなく、各画面で行う操作は1つにしました。スタッフは画面毎の単純な質問に答えるように操作していきます。(例えば、日本酒を選択するとおちょこの数を質問し、ワインだとグラスの数、焼酎だと飲み方、ソフトドリンクだと、氷の有無やアイスorホットを質問します。流れるように素早い操作が可能なように心がけましたが、そうすると一方でミスが増える可能性がでてきます。注文が3種類以上の時は自動的に【注文内容は大丈夫?】画面に遷移するようにしました!ここの画面から、商品の追加や数量変更・削除も可能です。1SoftKeyboardのフォーカス調節あとは、小さなことなんですが、注文の最後の画面では、EditTextのフォーカスをデフォルトで外しているのですが、メモを残すボタンタップ時にソフトキーボードがでてくるようにしました!このコード👇で、ソフトキーボードを出す実装ができます。2ホーム画面整理これは、システム関係ないのですが、もし誤操作でホーム画面に戻ってしまっても、一目でどれが伝票システムアプリかわかるようにしました。(完全人力)終わりにハード機器の選定から、DB設計、UIまで、全部自分1人でやると色々わかってきますが、1番思うことは、自分のレベルの低さです。(本当に)そして、フィードバックの大切さ。個人開発のアプリでは今回のような直接的なフィードバックがない分、色々なLogや、ユーザーのデータが相当すると思うので、次に活かしたいです。あとはメンターの大切さ。今回自分は登録だけして使いませんでしたが、英語版ではCodeMentor、日本語版ではMENTAなどがあるので、積極的に利用していきたいです。Twitterもよろしく(';')Crieitは個人で開発中です。どんな軽い内容でも嬉しいです。Crieitを作ろうと思ったかまた、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!ボードとは?関連記事Retrofit2で自己証明書のサーバへのアクセスできるようにするスワイプで気になるAV女優を探すことができる「AVキャッチャー」というサービスをリリースしました。