# 機能設計書 36-チェックアウト画面

## 概要

本ドキュメントは、注文確定プロセスのメイン画面であるチェックアウト画面の設計を記述する。

### 本機能の処理概要

本機能は、カート画面から遷移し、注文確定に向けた一連のステップ（住所入力→配送方法選択→支払方法選択→注文確認）をウィザード形式で提供するメイン画面である。

**業務上の目的・背景**：ECサイトにおける購入フローの中核を担う画面。ユーザーがカートに入れた商品を実際に購入するために必要な情報（配送先、配送方法、支払方法）を順を追って入力し、最終確認を行う。ステップ形式により、ユーザーは進捗を把握しながら安心して購入手続きを完了できる。

**機能の利用シーン**：ユーザーがカート画面で「チェックアウト」ボタンをタップした際に本画面が表示される。

**主要な処理内容**：
1. カート画面からチェックアウト画面への遷移
2. 4ステップのウィザード形式UI表示（住所→配送→支払→確認）
3. 各ステップの入力状態管理
4. ダウンロード可能商品の場合、配送ステップをスキップ
5. 各ステップの完了条件に応じた次ステップへの遷移制御
6. 合計金額の動的更新表示
7. 「注文確定」ボタンによる注文完了画面への遷移

**関連システム・外部連携**：GraphQL APIを介したBagistoバックエンドとの通信

**権限による制御**：ログインユーザー・ゲストユーザー共に利用可能（住所入力フォームが異なる）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | カート画面 | 前画面 | チェックアウトボタンタップで遷移 |
| 14 | チェックアウト画面 | 主画面 | 注文確定プロセスのメイン画面 |

## 機能種別

画面制御・ステップウィザード処理

## 入力仕様

### 入力パラメータ（画面遷移パラメータ）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| total | String | No | カート合計金額 | - |
| cartScreenBloc | CartScreenBloc | No | カート画面のBloc参照 | - |
| cartDetailsModel | CartModel | No | カート詳細データ | - |
| isDownloadable | bool | No | ダウンロード商品フラグ | デフォルトfalse |

### 入力データソース

- カート画面からのナビゲーション引数

## 出力仕様

### 出力データ

各ステップで収集したデータを次ステップに引き継ぎ：
- 請求先住所情報
- 配送先住所情報
- 配送方法ID
- 支払方法ID

### 出力先

- 画面表示: ステップ別ビュー
- 注文完了画面への遷移

## 処理フロー

### 処理シーケンス

```
1. カート画面からチェックアウト画面を表示
   └─ CheckoutScreenへの遷移
2. 現在のステップに応じたビューを表示
   └─ currentIndexで制御（1:住所, 2:配送, 3:支払, 4:確認）
3. ユーザーが各ステップで情報を入力
   └─ callBackで親画面に値を渡す
4. 「次へ」ボタンで次ステップへ遷移
   └─ バリデーション後にcurrentIndexをインクリメント
5. 最終ステップで「注文確定」ボタン
   └─ orderPlacedScreenへ遷移
```

### フローチャート

```mermaid
flowchart TD
    A[カート画面] --> B[チェックアウト画面表示]
    B --> C{ログインユーザー?}
    C -->|Yes| D[登録住所選択ビュー]
    C -->|No| E[ゲスト住所入力フォーム]
    D --> F[配送方法選択]
    E --> F
    F --> G{ダウンロード商品?}
    G -->|Yes| H[支払方法選択へスキップ]
    G -->|No| I[配送方法選択ビュー]
    I --> H
    H --> J[注文確認ビュー]
    J --> K[注文確定]
    K --> L[注文完了画面]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-36-01 | ステップ順序 | 住所→配送→支払→確認の順序で進行 | 常時 |
| BR-36-02 | ダウンロード商品 | isDownloadable=trueの場合、配送ステップをスキップ | 該当商品含む場合 |
| BR-36-03 | 住所必須 | 請求先・配送先住所未入力では次ステップ不可 | ステップ1完了時 |
| BR-36-04 | 配送方法必須 | 配送方法未選択では次ステップ不可 | ステップ2完了時 |
| BR-36-05 | 支払方法必須 | 支払方法未選択では注文確定不可 | ステップ3完了時 |
| BR-36-06 | 同一住所オプション | 「請求先と同じ」チェックで配送先を自動設定 | 住所入力時 |

### 計算ロジック

- 合計金額はAPIレスポンスのgrandTotalを表示
- StreamControllerで金額の動的更新を管理

## データベース操作仕様

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

チェックアウト画面自体はデータの取得と一時保持のみ。永続化は各サブ機能で行う。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 住所取得 | addresses | SELECT | 登録済み住所一覧取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | 必須項目未入力 | 警告通知表示 |
| - | ネットワークエラー | API通信失敗 | エラー通知表示 |

### リトライ仕様

自動リトライなし。

## トランザクション仕様

チェックアウト画面自体はトランザクション管理対象外。

## パフォーマンス要件

- 画面遷移: 即座に応答
- API呼び出し: 各ステップで3秒以内

## セキュリティ考慮事項

- ログインユーザーは認証トークンで識別
- ゲストユーザーはセッションで管理
- 住所情報の暗号化通信（HTTPS）

## 備考

- AppBarのタイトルは現在のステップに応じて動的に変更
- 合計金額はステップ進行に応じてリアルタイム更新

---

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

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

### 推奨読解順序

#### Step 1: エントリーポイントを理解する

チェックアウト画面のメインウィジェットを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | メイン画面構成、ステップ管理 |

**主要処理フロー**:
- **31-68行目**: 状態変数の定義（住所情報、配送/支払ID等）
- **85-106行目**: AppBarのタイトル切り替え
- **108-363行目**: _getBodyメソッドでステップ別ビュー切り替え
- **385-603行目**: フッターの「次へ」/「注文確定」ボタン処理

#### Step 2: ヘッダービューを理解する

ステップインジケーターの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | checkout_header_view.dart | `lib/screens/checkout/view/checkout_header_view.dart` | ステップインジケーターUI |

#### Step 3: 各ステップのサブビューを理解する

4つのステップそれぞれの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | checkout_address_view.dart | `lib/screens/checkout/checkout_addres/view/checkout_address_view.dart` | 住所選択ビュー（ログインユーザー用） |
| 3-2 | guest_add_address_form.dart | `lib/screens/checkout/guest_add_address/view/guest_add_address_form.dart` | 住所入力フォーム（ゲスト用） |
| 3-3 | checkout_shipping_view.dart | `lib/screens/checkout/checkout_shipping/view/checkout_shipping_view.dart` | 配送方法選択ビュー |
| 3-4 | checkout_payment_view.dart | `lib/screens/checkout/checkout_payment/view/checkout_payment_view.dart` | 支払方法選択ビュー |
| 3-5 | checkout_order_review_view.dart | `lib/screens/checkout/checkout_review/view/checkout_order_review_view.dart` | 注文確認ビュー |

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

```
CheckoutScreen (メイン画面)
    │
    ├─ CheckoutHeaderView（ステップインジケーター）
    │
    ├─ _getBody() によるステップ別ビュー切り替え
    │      │
    │      ├─ Step 1: CheckoutAddressView or GuestAddAddressForm
    │      │      └─ CheckOutBloc / GuestAddressBloc
    │      │
    │      ├─ Step 2: CheckoutShippingPageView
    │      │      └─ CheckOutShippingBloc
    │      │
    │      ├─ Step 3: CheckoutPaymentView
    │      │      └─ CheckOutPaymentBloc
    │      │
    │      └─ Step 4: CheckoutOrderReviewView
    │             └─ CheckOutReviewBloc
    │
    └─ StreamBuilder（合計金額表示）
           └─ 「次へ」/「注文確定」ボタン
```

### データフロー図

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

カート情報 ────────────▶ CheckoutScreen ──────────▶ 画面表示
                              │
                        ステップ管理
                              │
     ┌─────────────────────────┼────────────────────────┐
     │                        │                        │
住所入力 ───▶ Step1 ────────▶ 住所データ保持 ────────▶ Step2へ
                              │
配送選択 ───▶ Step2 ────────▶ 配送IDデ保持 ────────▶ Step3へ
                              │
支払選択 ───▶ Step3 ────────▶ 支払ID保持 ─────────▶ Step4へ
                              │
確認     ───▶ Step4 ────────▶ 注文完了画面へ遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| checkout_screen.dart | `lib/screens/checkout/view/checkout_screen.dart` | ソース | メイン画面 |
| checkout_header_view.dart | `lib/screens/checkout/view/checkout_header_view.dart` | ソース | ステップインジケーター |
| checkout_address_view.dart | `lib/screens/checkout/checkout_addres/view/checkout_address_view.dart` | ソース | 住所選択ビュー |
| checkout_address_bloc.dart | `lib/screens/checkout/checkout_addres/bloc/checkout_address_bloc.dart` | ソース | 住所Bloc |
| checkout_shipping_view.dart | `lib/screens/checkout/checkout_shipping/view/checkout_shipping_view.dart` | ソース | 配送方法ビュー |
| checkout_shipping_bloc.dart | `lib/screens/checkout/checkout_shipping/bloc/checkout_shipping_bloc.dart` | ソース | 配送Bloc |
| checkout_payment_view.dart | `lib/screens/checkout/checkout_payment/view/checkout_payment_view.dart` | ソース | 支払方法ビュー |
| checkout_payment_bloc.dart | `lib/screens/checkout/checkout_payment/bloc/checkout_payment_bloc.dart` | ソース | 支払Bloc |
| checkout_order_review_view.dart | `lib/screens/checkout/checkout_review/view/checkout_order_review_view.dart` | ソース | 確認ビュー |
| checkout_review_bloc.dart | `lib/screens/checkout/checkout_review/bloc/checkout_review_bloc.dart` | ソース | 確認Bloc |
| guest_add_address_form.dart | `lib/screens/checkout/guest_add_address/view/guest_add_address_form.dart` | ソース | ゲスト住所フォーム |
