４０代おっさん面会予約アプリを作ってみる⑥

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## 前回の記事

<https://qiita.com/kou1121/items/bea7575176b07bd16bb9>
<https://qiita.com/kou1121/items/94ff8d65976dab98dfc8>
<https://qiita.com/kou1121/items/318fe6cc0e0564e533b4>
<https://qiita.com/kou1121/items/0226693e93937f9e375b>
<https://qiita.com/kou1121/items/7929e0df5ff549c8d640>

## 下記の場合にエラーを出す

- 定員より多い予約人数の場合
- 利用時間を超えている場合
- 開始時刻　>= 終了時刻　の場合
- 予約がかぶっている場合（下記の場合に被りが発生）
  - 登録済、終了時刻 > 新規登録、開始時刻
  - 登録済、開始時刻 < 新規登録、終了時刻

`app.py`

```python
# 定員以下の予約人数の場合
        if booked_num <= capacity:
            # 面会室予約
            url = 'http://127.0.0.1:8000/bookings'
            res = requests.post(
                url,
                data=json.dumps(data)
            )
            if res.status_code == 200:
                st.success('予約完了しました')
            st.json(res.json())

        else:
            st.error(f'{room_name}の定員は、{capacity}名です。')
```

を書き直します

```python
# 定員より多い予約人数の場合
        if booked_num > capacity:
            st.error(f'{room_name}の定員は、{capacity}名です。')

        #  開始時刻　>= 終了時刻
        elif start_time >= end_time:
            st.error('開始時刻が終了時刻を越えています')
        
        #  利用時間を超えている場合
        elif start_time < datetime.time(hour=9, minute=0, second=0) or end_time > datetime.time(hour=20, minute=0, second=0):
            st.error('面会時間は9：00～20：00になります')
            
        #  すべてが大丈夫ならAPIをたたく
        else:
            # 面会室予約
            url = 'http://127.0.0.1:8000/bookings'
            res = requests.post(
                url,
                data=json.dumps(data)
            )
            if res.status_code == 200:
                st.success('予約完了しました')
            elif res.status_code == 404 and res.json()['detail'] == "その時間で予約されています":
                st.error('指定の時間にはすでに予約が入っています。')

            st.json(res.json())
```

次は
- 予約がかぶっている場合（下記の場合に被りが発生）
  - 登録済、終了時刻 > 新規登録、開始時刻
  - 登録済、開始時刻 < 新規登録、終了時刻

こちらは
`crud.py`の予約登録部分を書き直す

```python
# 予約登録
def create_booking(db: Session, booking: schemas.Booking): # schemas.Bookingのデータ構造のクラスを受け取る
    db_booked = db.query(models.Booking).\
        filter(models.Booking.room_id == booking.room_id).\
        filter(models.Booking.end_datetime > booking.start_datetime).\
        filter(models.Booking.start_datetime < booking.end_datetime).\
        all()
#  重複するデータがなければ
    if len(db_booked) == 0:
        db_booking = models.Booking(
            user_id = booking.user_id,
            room_id = booking.room_id,
            booked_num = booking.booked_num,
            start_datetime = booking.start_datetime,
            end_datetime = booking.end_datetime
        ) # インスタンスの生成
        db.add(db_booking) #データベースに追加
        db.commit() # コミット
        db.refresh(db_booking) # インスタンスをリフレッシュ
        return db_booking
    else:
        raise HTTPException(status_code=404, detail="その時間で予約されています")
```

`db_booking = db.query(models.Booking)`予約テーブルのデータを持ってきている。
`filter`を使用して
`filter(models.Booking.room_id == booking.room_id)`今予約しているroom_idと予約テーブルの予約room_idが一緒の物を持ってくる
`filter(models.Booking.end_datetime > booking.start_datetime).\
 filter(models.Booking.start_datetime < booking.end_datetime).\`
登録済、終了時刻 > 新規登録、開始時刻
登録済、開始時刻 < 新規登録、終了時刻
を見ている。

重複値がない場合は
`if len(db_booked) == 0:`から記入している
`else`からは重複した値のエラーを出している。

上にインポート文

`from fastapi import HTTPException`を記入
エラーをjsonデータで出している。

`app.py`を見て以下を追加

```python
# 面会室予約
            url = 'http://127.0.0.1:8000/bookings'
            res = requests.post(
                url,
                data=json.dumps(data)
            )
            if res.status_code == 200:
                st.success('予約完了しました')
            elif res.status_code == 404 and res.json()['detail'] == "その時間で予約されています": # 追加された分
                st.error('指定の時間にはすでに予約が入っています。')

            st.json(res.json())
```

## 参考

https://www.udemy.com/course/python-fastapi