lesson-2_予約機能を完成させよう
🖋 予約機能を完成させよう
このレッスンでは、予約機能を完成させるためにChange
メソッドを追加していきます。
まずは、宿泊者が部屋を予約するためのメソッドを実装していきます。
以下のコードを追加しましょう。exists
メソッドの下に追加すると良いでしょう。
/contract/src/lib.rs
pub fn exists(&self, owner_id: AccountId, room_name: String) -> bool {
...
}
+ // 部屋を予約する
+ #[payable]
+ pub fn book_room(&mut self, room_id: RoomId, check_in_date: CheckInDate) {
+ let room = self
+ .rooms_by_id
+ .get_mut(&room_id)
+ .expect("ERR_NOT_FOUND_ROOM");
+
+ let account_id = env::signer_account_id();
+
+ // 関数コール時に送付されたNEARを取得
+ let deposit = env::attached_deposit();
+ // 送付されたNEARと実際の宿泊料(NEAR)を比較するためにキャストをする
+ let room_price: u128 = room.price.into();
+ assert_eq!(deposit, room_price, "ERR_DEPOSIT_IS_INCORRECT");
+
+ // 予約が入った日付, 宿泊者IDを登録
+ room.booked_info
+ .insert(check_in_date.clone(), account_id.clone());
+
+ // 宿泊者に予約データを保存
+ let owner_id = room.owner_id.clone();
+ self.add_booking_to_guest(account_id, room_id, check_in_date);
+
+ // 宿泊料を部屋のオーナーへ支払う
+ Promise::new(owner_id).transfer(deposit);
+ }
pub fn get_rooms_registered_by_owner(&self, owner_id: AccountId) -> Vec<ResigteredRoom> {
...
}
追加した内容を見ていきましょう。
book_room
メソッドでは、宿泊データを保存し実際に宿泊料をオーナーへ送信します。このメソッドには、#[payable]
アノテーションが指定されています。これをメソッドに指定することで、呼び出しとトークンの転送ができるようになります。
まずは、予約される部屋のデータを取得します。ここで、データの取得にget_mut()
を使用していることに注目してください。mut
はmutable
の意味で、変更可能なroom
が取得できます。予約データを追加し、room
を更新したいので可変のデータが取得できるget_mut()
を使います。
let room = self
.rooms_by_id
.get_mut(&room_id)
.expect("ERR_NOT_FOUND_ROOM");
env::attached_deposit()
メソッドで、宿泊者が支払うNEARを取得します。
// 関数コール時に送付されたNEARを取得
let deposit = env::attached_deposit();
// 送付されたNEARと実際の宿泊料(NEAR)を比較するためにキャストをする
let room_price: u128 = room.price.into();
assert_eq!(deposit, room_price, "ERR_DEPOSIT_IS_INCORRECT");
取得したdeposit
の型はU128
です。deposit
がオーナーの掲載する宿泊料と等しいか比較をするために、u128
に型変換をしています。変換にはinto()
メソッドを使用しています。
assert_eq!()
メソッドで比較をし、もし等しくなければエラーとなります。
次に、予約データをブロックチェーン上へ保存します。中で呼んでいるadd_booking_to_guest
メソッドは、後ほど実装します。
// 予約が入った日付, 宿泊者IDを登録
room.booked_info
.insert(check_in_date.clone(), account_id.clone());
// 宿泊者に予約データを保存
let owner_id = room.owner_id.clone();
self.add_booking_to_guest(account_id, room_id, check_in_date);
最後に、宿泊料をオーナーへ支払います。transfer()
メソッドは、引数に受け取ったトークンをPromise
が動作するアカウントに転送します。Promise
は、オーナーのアカウントIDを指定して作成されていることに注目してください。ここでは、「Promise
が動作するアカウント」が部屋を登録したオーナーとなります。よって、部屋のオーナーにトークンが転送されます。
// 宿泊料を部屋のオーナーへ支払う
Promise::new(owner_id).transfer(deposit);