# 画面設計書 107-予約編集

## 概要

本ドキュメントは、QuickerSiteの予約カレンダー機能における予約編集画面（bs_ac_booking.asp）の設計書です。予約情報の新規登録・編集・削除を行う管理画面について記載しています。

### 本画面の処理概要

予約編集画面は、特定のカレンダーに対する予約の登録・編集を行うための画面です。予約日時、予約者情報、ステータスなどを入力し、重複チェックを経て保存します。

**業務上の目的・背景**：予約管理において、顧客からの予約リクエストを登録し、ステータス（確定/保留/利用不可）を管理することは重要な業務です。本画面では、開始日・終了日を日付ピッカーで選択し、午前のみ/午後のみの半日予約にも対応しています。重複予約を自動でチェックし、ダブルブッキングを防止します。

**画面へのアクセス方法**：カレンダー管理画面（bs_ac.asp）からcalAction=bookingパラメータを指定してアクセスします。予約一覧の「Modify」リンク、または「Add Reservation」リンクからも遷移できます。

**主要な操作・処理内容**：
1. 予約情報の入力（ステータス、開始日、終了日、名前、メール、電話、メモ）
2. 半日予約オプション（午後のみ開始/午前のみ終了）
3. 重複チェック付きの保存処理
4. 予約の削除（確認ダイアログ付き）
5. メモ内容のポップアップ表示（seeNotes=1時）

**画面遷移**：カレンダー管理画面（bs_ac.asp）からインクルードされます。保存・削除後は予約一覧画面へリダイレクトします。

**権限による表示制御**：親画面（bs_ac.asp）でセカンドアドミンのbAvailabilityCal権限チェックが行われます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 75 | カレンダー予約管理 | 主機能 | 予約の詳細編集 |

## 画面種別

登録 / 編集

## URL/ルーティング

`asp/bs_ac.asp?calAction=booking&iCalID={カレンダーID}&iBookingID={予約ID}`

パラメータ：
- `calAction`：booking（固定）
- `iCalID`：対象カレンダーID
- `iBookingID`：予約ID（新規作成時は指定なし）
- `seeNotes`：1の場合、メモ内容のみをポップアップ表示

## 入出力項目

| 項目名 | 項目ID | 型 | 必須 | 最大長 | 説明 |
|--------|--------|-----|------|--------|------|
| ステータス | iStatus | select | - | - | 予約ステータス（Confirmed/Pending/Unavailable） |
| 開始日 | dStartDate | text | * | 13 | 日付ピッカー対応 |
| 午後のみ開始 | bSOnlyAfternoon | checkbox | - | - | 開始日の午後から |
| 終了日 | dEndDate | text | * | 13 | 日付ピッカー対応 |
| 午前のみ終了 | bEOnlyMorning | checkbox | - | - | 終了日の午前まで |
| 名前 | sName | text | * | 50 | 予約者名 |
| メール | sEmail | email | - | 50 | メールアドレス |
| 電話 | sPhone | text | - | 50 | 電話番号 |
| メモ | sNotes | richtext | - | - | WYSIWYGエディタ |
| postback | postback | hidden | - | - | POSTバック判定フラグ |
| calaction | calaction | hidden | - | - | booking（固定） |
| iBookingID | iBookingID | hidden | - | - | 予約ID |
| iCalID | iCalID | hidden | - | - | カレンダーID |

## 表示項目

| 項目名 | 説明 |
|--------|------|
| カレンダー名 | 対象カレンダーの名称（読取専用） |
| Unique ID | 予約ID（既存予約編集時のみ表示） |
| ステータス選択 | Confirmed/Pending/Unavailableから選択 |
| 開始日入力欄 | 日付ピッカー付きテキストボックス |
| 午後のみチェック | 半日予約用チェックボックス |
| 終了日入力欄 | 日付ピッカー付きテキストボックス |
| 午前のみチェック | 半日予約用チェックボックス |
| 名前入力欄 | 予約者名テキストボックス |
| メール入力欄 | メールアドレス（type=email） |
| 電話入力欄 | 電話番号テキストボックス |
| メモ入力欄 | FCKEditorによるリッチテキストエディタ |
| 保存ボタン | 予約を保存 |
| 削除ボタン | 予約を削除（既存予約時のみ） |
| 予約一覧リンク | Back to list of reservations |
| カレンダープレビュー | 12ヶ月分のカレンダー表示 |

## イベント仕様

### 1-保存ボタン押下

1. フォームデータをPOSTで送信
2. btActが「Save」の場合：
   - booking.getRequestValues()でフォーム値を取得
   - booking.save()を呼び出し
   - check()関数内で入力検証と重複チェック
   - 検証成功時：tblCalendarBookingに保存
   - 予約一覧画面へリダイレクト

### 2-削除ボタン押下

1. JavaScriptのconfirmダイアログで削除確認
2. btActが「Delete」の場合：
   - booking.delete()を呼び出し
   - tblCalendarBookingから削除
   - 予約一覧画面へリダイレクト

### 3-メモポップアップ表示（seeNotes=1）

1. response.clearでバッファクリア
2. 予約者名とメモ内容のみをHTML出力
3. Modifyリンクを含む
4. response.endで処理終了

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下（新規） | tblCalendarBooking | INSERT | 新規予約レコードを作成 |
| 保存ボタン押下（更新） | tblCalendarBooking | UPDATE | 既存予約レコードを更新 |
| 削除ボタン押下 | tblCalendarBooking | DELETE | 予約レコードを削除 |

### テーブル別更新項目詳細

#### tblCalendarBooking

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | iId | 自動採番 | 主キー |
| INSERT/UPDATE | iStatus | フォーム選択値 | ステータスコード |
| INSERT/UPDATE | dStartDate | フォーム入力値（日付変換） | 開始日 |
| INSERT/UPDATE | dEndDate | フォーム入力値（日付変換） | 終了日 |
| INSERT/UPDATE | bSOnlyAfternoon | チェックボックス | 午後のみ開始 |
| INSERT/UPDATE | bEOnlyMorning | チェックボックス | 午前のみ終了 |
| INSERT/UPDATE | sName | フォーム入力値 | 予約者名 |
| INSERT/UPDATE | sEmail | フォーム入力値 | メールアドレス |
| INSERT/UPDATE | sPhone | フォーム入力値 | 電話番号 |
| INSERT/UPDATE | sNotes | フォーム入力値 | メモ |
| INSERT/UPDATE | iCalendarID | フォームhidden値 | カレンダーID |
| INSERT | dCreatedTS | now() | 作成日時 |
| INSERT/UPDATE | dUpdatedTS | now() | 更新日時 |
| DELETE | - | WHERE iId={予約ID} | 条件 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| err_mandatory | エラー | 必須項目が入力されていません | 名前・開始日・終了日が空の場合 |
| - | エラー | End date cannot be before start date! | 終了日が開始日より前の場合 |
| - | エラー | Double bookings are not allowed! | 重複予約の場合 |
| - | 確認 | Are you sure to delete this reservation? | 削除ボタン押下時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 必須項目未入力 | エラーメッセージを表示し、フォームを再表示 |
| 日付範囲エラー | customErrorMessageでエラー表示 |
| 重複予約 | customErrorMessageでエラー表示、保存中止 |

## 備考

- 重複チェックは半日予約（午後のみ/午前のみ）を考慮
- 同じ日の午後終了と午前開始は許可される
- 日付入力にはjQuery DatePickerを使用
- メモ（sNotes）の編集にはFCKEditorを使用
- カレンダープレビューは右側に表示（12ヶ月分）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ac_calendarbooking.asp | `asp/includes/ac_calendarbooking.asp` | cls_calendarbookingクラス全体、特にcheck()関数（43-96行目）の重複チェックロジック |

**読解のコツ**: check()関数内の重複チェックは、開始日・終了日の比較と半日フラグの組み合わせで判定されます。

#### Step 2: 画面本体を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bs_ac_booking.asp | `asp/bs_ac_booking.asp` | 予約編集フォームとPOSTバック処理 |

**主要処理フロー**:
1. **2-6行目**: カレンダー・予約オブジェクト生成、データ取得
2. **7-11行目**: seeNotes=1時のポップアップ表示処理
3. **12-23行目**: POSTバック処理（Save/Delete分岐）
4. **24行目以降**: フォームHTML出力、カレンダープレビュー

### プログラム呼び出し階層図

```
bs_ac.asp（親画面）
    │
    └─▶ bs_ac_booking.asp（インクルード）
            │
            ├─ cls_calendar
            │      └─ pick()（カレンダーデータ取得）
            │
            ├─ cls_calendarbooking
            │      ├─ pick()（予約データ取得）
            │      ├─ getRequestValues()（フォーム値取得）
            │      ├─ save()（予約保存）
            │      │      └─ check()（入力検証・重複チェック）
            │      └─ delete()（予約削除）
            │
            ├─ cls_statusList
            │      └─ showSelected()（ステータスドロップダウン）
            │
            ├─ JQDatePickerFT()（日付ピッカー初期化）
            │
            ├─ createFCKInstance()（WYSIWYGエディタ）
            │
            └─ bs_ac_view.asp（カレンダープレビュー）
```

### データフロー図

```
[入力]                    [処理]                         [出力]

ブラウザ（GET）     ───▶ bs_ac_booking.asp           ───▶ 編集フォームHTML
?iBookingID=xxx           ├─ booking.pick(iBookingID)
                          └─ フォーム表示

ブラウザ（POST）    ───▶ bs_ac_booking.asp           ───▶ リダイレクト
フォームデータ            ├─ booking.getRequestValues()
btAct=Save                ├─ booking.save()
                          │      ├─ check()
                          │      │      ├─ 必須チェック
                          │      │      ├─ 日付範囲チェック
                          │      │      └─ 重複チェック
                          │      │             └─ calObj.bookings()
                          │      └─ INSERT/UPDATE
                          └─▶ bs_ac.asp?calAction=bookings

ブラウザ（GET）     ───▶ bs_ac_booking.asp           ───▶ ポップアップHTML
?seeNotes=1               └─ メモ内容のみ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bs_ac_booking.asp | `asp/bs_ac_booking.asp` | ソース | 予約編集画面本体 |
| bs_ac.asp | `asp/bs_ac.asp` | ソース | 親画面（ルーター） |
| bs_ac_bookings.asp | `asp/bs_ac_bookings.asp` | ソース | 予約一覧画面 |
| bs_ac_view.asp | `asp/bs_ac_view.asp` | ソース | カレンダービュー |
| ac_calendar.asp | `asp/includes/ac_calendar.asp` | ソース | cls_Calendarクラス |
| ac_calendarbooking.asp | `asp/includes/ac_calendarbooking.asp` | ソース | cls_calendarbookingクラス |
| ac_statuslist.asp | `asp/includes/ac_statuslist.asp` | ソース | cls_statusListクラス |
