# 画面設計書 16-注文完了画面

## 概要

本ドキュメントは、Bagisto eコマースモバイルアプリにおける注文完了画面の設計仕様を定義するものです。注文完了画面は、チェックアウトプロセスの最終段階で注文が確定した後に表示される確認画面です。

### 本画面の処理概要

注文完了画面は、注文確定処理を実行し、その結果（注文ID、確認メッセージ）を表示する画面です。PayPal決済にも対応しています。

**業務上の目的・背景**：注文完了画面は、ユーザーに購入完了を明確に伝え、注文IDを提示することで、安心感を与える重要な画面です。また、「買い物を続ける」ボタンでホーム画面へ誘導したり、「注文詳細」リンクで注文内容を確認できるようにすることで、継続的な購買行動を促進します。PayPal決済の場合は、決済処理を行ってから注文を確定します。

**画面へのアクセス方法**：
- チェックアウト画面のステップ4で「注文確定」ボタンを押下
- PayPal決済完了後にリダイレクト

**主要な操作・処理内容**：
1. 注文確定APIの呼び出し（SaveOrder）
2. PayPal決済処理（PayPal Standard/Smart Button対応）
3. 注文完了メッセージの表示
4. 注文ID（注文番号）の表示
5. 「買い物を続ける」ボタンでホーム画面へ遷移
6. 注文IDタップで注文詳細画面へ遷移（ログインユーザーのみ）

**画面遷移**：
- 遷移元：チェックアウト画面（ステップ4）
- 遷移先：ホーム画面、注文詳細画面

**権限による表示制御**：注文詳細へのリンクはログインユーザーのみ有効です。ゲストユーザーは注文IDのみ表示されます。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 40 | 注文確定 | 主機能 | 注文完了後の確認画面表示（注文ID、確認メッセージ） |

## 画面種別

完了（確認）

## URL/ルーティング

```dart
const String orderPlacedScreen = 'orderPlacedScreen';
```

ルート定義：`Navigator.pushReplacementNamed(context, orderPlacedScreen, arguments: cartModel)`

## 入出力項目

| 項目名 | 入力/出力 | 型 | 必須 | 説明 |
|--------|----------|-----|------|------|
| cartModel | 入力 | CartModel? | × | カートデータ（PayPal決済情報を含む） |

## 表示項目

| No | 項目名 | 型 | 表示条件 | 説明 |
|----|--------|-----|----------|------|
| 1 | 注文受付メッセージ | Text | 注文成功 | 「ORDER RECEIVED」等のメッセージ |
| 2 | お礼メッセージ | Text | 注文成功 | 「Thank you」等のメッセージ |
| 3 | 注文ID | Text | 注文成功 | 「Your Order ID: xxx」形式で表示 |
| 4 | 確認メッセージ | Text | 注文成功 | 注文確認メール送信メッセージ |
| 5 | 買い物を続けるボタン | MaterialButton | 注文成功 | ホーム画面への遷移ボタン |
| 6 | ローディング | Loader | 処理中 | 注文確定処理中の表示 |
| 7 | PayPal決済画面 | PaypalCheckoutView | PayPal決済 | PayPal決済WebView |
| 8 | エラーメッセージ | ErrorMessage | エラー時 | 注文失敗時のエラー表示 |

## イベント仕様

### 1-注文確定処理（通常決済）

**トリガー**：画面初期表示時（PayPal以外の場合）

**処理フロー**：
1. `SaveOrderBloc`に`SaveOrderFetchDataEvent`を発行
2. `SaveOrderRepository.savePaymentReview()`でAPIを呼び出し
3. 成功時：`SaveOrderFetchDataState.success`を発行
4. 注文完了ビューを表示（`_orderPlacedView`）

### 2-PayPal Standard決済処理

**トリガー**：画面初期表示時（支払方法がpaypal_standardの場合）

**処理フロー**：
1. PayPal設定をロード（sandbox/production、client_id、secret）
2. `PaypalCheckoutView`を表示
3. ユーザーがPayPalで決済を完了
4. コールバック`onSuccess`で決済結果を取得
5. 決済情報を`serverPayload`として`SaveOrderFetchDataEvent`を発行
6. 注文確定処理を実行

### 3-PayPal Smart Button決済処理

**トリガー**：画面初期表示時（支払方法がpaypal_smart_buttonの場合）

**処理フロー**：
1. PayPal設定をロード
2. ネイティブ側のPayPal SDKを呼び出し（MethodChannel）
3. 決済完了後、`paypalPaymentResult`コールバックを受信
4. orderIDを含む`serverPayload`を作成
5. `SaveOrderFetchDataEvent`を発行して注文確定

### 4-ホーム画面遷移

**トリガー**：「買い物を続ける」ボタン押下

**処理フロー**：
1. `Navigator.pushReplacementNamed(context, home)`を実行
2. ホーム画面へ遷移

### 5-注文詳細画面遷移

**トリガー**：注文IDテキストタップ（ログインユーザーのみ）

**処理フロー**：
1. `Navigator.pushNamed(context, orderDetailPage, arguments: orderId)`を実行
2. 注文詳細画面へ遷移

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 注文確定 | orders | INSERT | 注文レコードを作成 |
| 注文確定 | order_items | INSERT | 注文商品レコードを作成 |
| 注文確定 | order_addresses | INSERT | 注文住所レコードを作成 |
| 注文確定 | order_payment | INSERT | 支払情報レコードを作成 |
| 注文確定 | cart, cart_items | DELETE | カートをクリア |

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

#### orders

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id, increment_id, status, customer_id, grand_total, etc. | カート情報から生成 | 注文番号は自動採番 |

## メッセージ仕様

| No | メッセージID | メッセージ内容 | 表示タイミング | 種別 |
|----|------------|---------------|--------------|------|
| 1 | orderReceivedMsg | ORDER RECEIVED | 注文成功時 | 成功 |
| 2 | thankYouMsg | Thank you | 注文成功時 | 成功 |
| 3 | yourOrderIdMsg | Your Order ID: | 注文ID表示 | 情報 |
| 4 | orderConfirmationMsg | We have sent you order confirmation email... | 注文成功時 | 情報 |
| 5 | continueShopping | CONTINUE SHOPPING | ボタンラベル | 情報 |
| 6 | addMoreProductsMsg | （追加商品メッセージ） | エラー時 | エラー |
| 7 | orderNote | Order Note | PayPal決済時 | 情報 |

## 例外処理

| No | 例外状況 | 対応処理 |
|----|---------|---------|
| 1 | 注文確定APIエラー | `ErrorMessage.errorMsg`でエラー表示 |
| 2 | PayPal決済キャンセル | `Navigator.pop`で前画面に戻る |
| 3 | PayPal決済エラー | エラー通知表示、前画面に戻る |
| 4 | ネットワークエラー | エラーメッセージ表示 |
| 5 | 在庫切れ等の注文エラー | エラーメッセージ表示（追加商品促進） |

## 備考

- PayPal決済は「paypal_standard」と「paypal_smart_button」の2種類に対応
- PayPal設定はGlobalData.configDataから取得
- サンドボックスモードの設定も設定ファイルから取得
- 注文IDリンクはログインユーザーのみ青色でクリッカブル
- `pushReplacementNamed`で遷移するため、この画面から戻ることはできない
- PayPal Smart Buttonはネイティブ（iOS/Android）のMethodChannelを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | save_order_model.dart | `lib/screens/checkout/data_model/save_order_model.dart` | SaveOrderModel、Orderクラスの構造 |
| 1-2 | cart_data_model.dart | `lib/screens/cart_screen/cart_model/cart_data_model.dart` | CartModel（入力パラメータ） |

**読解のコツ**: `SaveOrderModel`には`order`（注文情報）と`redirectUrl`（外部決済リダイレクト用）が含まれます。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | save_order.dart | `lib/screens/checkout/checkout_save_order/view/save_order.dart` | CheckOutSaveOrderクラス |

**主要処理フロー**:
1. **行35-72**: initStateでPayPal判定、設定ロード、イベント発行
2. **行75-77**: `_isPaypalMethod`でPayPal決済かどうか判定
3. **行156-173**: BlocConsumerでUI構築
4. **行176-199**: `buildUI`で状態に応じたUI切り替え
5. **行201-314**: `_orderPlacedView`で注文完了画面表示
6. **行316-354**: `paypalView`でPayPal決済画面表示

#### Step 3: 状態管理（BLoC）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | save_order_bloc.dart | `lib/screens/checkout/checkout_save_order/bloc/save_order_bloc.dart` | 注文確定処理 |
| 3-2 | save_order_event.dart | `lib/screens/checkout/checkout_save_order/bloc/save_order_event.dart` | イベント定義 |
| 3-3 | save_oredr_state.dart | `lib/screens/checkout/checkout_save_order/bloc/save_oredr_state.dart` | 状態定義 |

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

```
CheckOutSaveOrder (save_order.dart)
    │
    ├─ [通常決済]
    │      └─ SaveOrderBloc.SaveOrderFetchDataEvent
    │             └─ SaveOrderRepository.savePaymentReview()
    │
    ├─ [PayPal Standard]
    │      └─ PaypalCheckoutView
    │             └─ onSuccess → SaveOrderBloc.SaveOrderFetchDataEvent
    │
    ├─ [PayPal Smart Button]
    │      └─ MethodChannel.invokeMethod("paypalPay")
    │             └─ paypalPaymentResult → SaveOrderBloc.SaveOrderFetchDataEvent
    │
    └─ _orderPlacedView
           ├─ ホーム画面遷移 → Navigator.pushReplacementNamed(home)
           └─ 注文詳細遷移 → Navigator.pushNamed(orderDetailPage)
```

### データフロー図

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

CheckoutScreen           CheckOutSaveOrder              画面遷移
      │                        │                              │
      │ cartModel              │                              │
      └──────────▶ 決済判定 ────────────────────────────────────┤
                        │                                     │
                   ┌────┴────┐                                │
                   │         │                                │
              [通常決済] [PayPal決済]                           │
                   │         │                                │
                   └────┬────┘                                │
                        │                                     │
                   SaveOrderBloc                              │
                        │                                     │
                   SaveOrderModel                             │
                        │                                     │
                   _orderPlacedView ─────────────────────────▶│
                                                              │
                                                    ホーム画面/注文詳細
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| save_order.dart | `lib/screens/checkout/checkout_save_order/view/save_order.dart` | ソース | メイン画面ウィジェット |
| save_order_bloc.dart | `lib/screens/checkout/checkout_save_order/bloc/save_order_bloc.dart` | ソース | 状態管理BLoC |
| save_order_event.dart | `lib/screens/checkout/checkout_save_order/bloc/save_order_event.dart` | ソース | イベント定義 |
| save_oredr_state.dart | `lib/screens/checkout/checkout_save_order/bloc/save_oredr_state.dart` | ソース | 状態定義 |
| save_order_repositroy.dart | `lib/screens/checkout/checkout_save_order/bloc/save_order_repositroy.dart` | ソース | API通信 |
| save_order_model.dart | `lib/screens/checkout/data_model/save_order_model.dart` | ソース | データモデル |
| payment_web_view.dart | `lib/screens/checkout/checkout_save_order/view/payment_web_view.dart` | ソース | 外部決済WebView |
| route_constants.dart | `lib/utils/route_constants.dart` | 設定 | ルート定数定義 |
