# 機能設計書 42-注文詳細表示

## 概要

本ドキュメントは、ECモバイルアプリケーションにおける注文詳細表示機能の設計仕様を定義する。個別注文の詳細情報（商品明細、配送先、支払い情報、ステータス等）を表示し、注文キャンセルや再注文、請求書・配送・返金詳細への遷移を可能にする機能である。

### 本機能の処理概要

この機能は、注文一覧画面から選択された特定の注文について、その詳細な情報をすべて表示する。商品情報、価格内訳、配送情報、支払い方法など、注文に関するすべての情報を一画面で確認できる。

**業務上の目的・背景**：ユーザーが注文内容を詳細に確認できることは、EC取引の透明性を確保する上で不可欠である。商品の間違いがないか、配送先が正しいか、支払い金額が適切かなど、注文に関する疑問をすべて解消できる環境を提供する。また、問題発生時のキャンセル処理や、満足した商品の再注文をスムーズに行えるようにする。

**機能の利用シーン**：注文履歴一覧から特定の注文をタップした際に利用される。配送状況の確認、注文内容の確認、キャンセルの検討、再注文の実行、請求書・配送詳細・返金詳細の確認など、多岐にわたる場面で使用される。

**主要な処理内容**：
1. GraphQL APIを通じて注文詳細データを取得
2. 注文基本情報（注文番号、日付、ステータス）の表示
3. 注文商品一覧（商品名、数量、価格、配送状況）の表示
4. 価格詳細（小計、配送料、税金、割引、合計）の表示
5. 配送先・請求先住所の表示
6. 支払い方法の表示
7. 請求書・配送・返金詳細画面への遷移ボタン表示

**関連システム・外部連携**：バックエンドのBagisto GraphQL APIと連携し、注文詳細データを取得する。注文キャンセルや再注文の処理もAPIを通じて実行される。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。ユーザーは自身の注文のみを閲覧できる。キャンセルボタンはステータスが「pending」の場合のみ表示される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | 注文詳細画面 | 主画面 | 個別注文の詳細情報表示（商品明細、配送先、支払い情報、ステータス） |
| 17 | 注文履歴一覧画面 | 参照元画面 | 注文一覧から詳細画面へ遷移 |
| 19 | 請求書詳細画面 | 遷移先画面 | 請求書詳細ボタンから遷移 |
| 20 | 配送詳細画面 | 遷移先画面 | 配送詳細ボタンから遷移 |
| 21 | 返金詳細画面 | 遷移先画面 | 返金詳細ボタンから遷移 |

## 機能種別

データ取得 / 詳細表示 / 画面遷移

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| orderId | int | Yes | 注文の内部ID | 正の整数 |

### 入力データソース

- 画面遷移引数：注文一覧画面からのorderId
- ユーザーセッション：認証トークン（SharedPreferencesから取得）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | int | 注文の内部ID |
| incrementId | String | 注文番号（表示用） |
| status | String | 注文ステータス |
| createdAt | String | 注文日時 |
| shippingTitle | String | 配送方法名 |
| items | List<Items> | 注文商品一覧 |
| items[].name | String | 商品名 |
| items[].sku | String | 商品SKU |
| items[].qtyOrdered | int | 注文数量 |
| items[].qtyShipped | int | 出荷数量 |
| items[].qtyInvoiced | int | 請求済み数量 |
| items[].qtyCanceled | int | キャンセル数量 |
| items[].qtyRefunded | int | 返金数量 |
| items[].formattedPrice | FormattedPrice | フォーマット済み価格情報 |
| formattedPrice.subTotal | String | 小計 |
| formattedPrice.shippingAmount | String | 配送料 |
| formattedPrice.taxAmount | String | 税額 |
| formattedPrice.discountAmount | String | 割引額 |
| formattedPrice.grandTotal | String | 合計金額 |
| billingAddress | BillingAddress | 請求先住所 |
| shippingAddress | BillingAddress | 配送先住所 |
| payment.methodTitle | String | 支払い方法名 |

### 出力先

- 画面表示：OrderDetailTileウィジェットによる詳細情報表示

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ OrderDetailBlocを取得し、OrderDetailFetchDataEventを発行
2. API呼び出し
   └─ OrderDetailRepositoryImpがApiClient経由でGraphQL APIを呼び出し
3. レスポンス処理
   └─ OrderDetailにデシリアライズ
4. 状態更新
   └─ OrderDetailFetchDataStateをemitしてUI更新
5. 詳細表示
   └─ OrderDetailTileで注文詳細をセクション別に表示
6. ユーザー操作待機
   └─ キャンセル/再注文/請求書・配送・返金詳細遷移ボタン
```

### フローチャート

```mermaid
flowchart TD
    A[画面表示開始] --> B[OrderDetailBloc初期化]
    B --> C[OrderDetailFetchDataEvent発行]
    C --> D[API呼び出し]
    D --> E{レスポンス成功?}
    E -->|Yes| F[OrderDetail生成]
    E -->|No| G[エラー表示]
    F --> H[注文詳細表示]
    H --> I{ステータス=pending?}
    I -->|Yes| J[キャンセルボタン表示]
    I -->|No| K[キャンセルボタン非表示]
    J --> L[ユーザー操作待機]
    K --> L
    L --> M{操作種別}
    M -->|キャンセル| N[キャンセル確認ダイアログ]
    M -->|再注文| O[ReOrderEvent発行]
    M -->|請求書| P[請求書画面遷移]
    M -->|配送| Q[配送詳細画面遷移]
    M -->|返金| R[返金詳細画面遷移]
    N --> S{確認OK?}
    S -->|Yes| T[CancelOrderEvent発行]
    S -->|No| L
    T --> U[キャンセルAPI呼び出し]
    O --> V[再注文API呼び出し]
    V --> W[カート画面遷移]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-42-01 | 認証必須 | ログイン済みユーザーのみ注文詳細を閲覧可能 | 常時 |
| BR-42-02 | 自己注文のみ | ユーザーは自身の注文のみ閲覧可能 | 常時 |
| BR-42-03 | キャンセル条件 | ステータスが「pending」の場合のみキャンセル可能 | 常時 |
| BR-42-04 | 再注文制限 | バンドル商品を含む注文は再注文不可 | items.type='bundle'を含む場合 |
| BR-42-05 | 請求書ボタン表示 | qtyInvoiced > 0 の場合のみ請求書ボタン表示 | 常時 |
| BR-42-06 | 配送ボタン表示 | qtyShipped > 0 の場合のみ配送詳細ボタン表示 | 常時 |
| BR-42-07 | 返金ボタン表示 | qtyRefunded > 0 の場合のみ返金詳細ボタン表示 | 常時 |

### 計算ロジック

割引表示判定：
```dart
if (formattedPrice?.discountAmount != "\$0.00") {
  // 割引行を表示
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 注文詳細取得 | orders | SELECT | 注文IDに紐づく注文を取得 |
| 注文詳細取得 | order_items | SELECT | 注文に含まれる商品情報を取得 |
| 注文詳細取得 | order_addresses | SELECT | 配送先・請求先住所を取得 |
| 注文詳細取得 | order_payment | SELECT | 支払い情報を取得 |

### テーブル別操作詳細

#### orders（GraphQL API経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, increment_id, status, created_at, shipping_title等 | id = 指定されたorderId | 単一注文取得 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API通信エラー | ネットワーク接続不可 | エラーメッセージ表示 |
| - | 認証エラー | セッション切れ | ログイン画面へリダイレクト |
| - | データなし | 注文が存在しない | NoDataFound表示 |
| - | キャンセル失敗 | API処理エラー | エラー通知表示 |
| - | 再注文失敗 | API処理エラー | エラー通知表示 |

### リトライ仕様

- RefreshIndicatorによるプルトゥリフレッシュ機能を提供
- 再読み込み時は同一orderIdでデータを再取得

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

- 注文詳細取得：読み取りのみのためトランザクション管理不要
- キャンセル処理：API側でトランザクション管理（フロントは単一API呼び出し）
- 再注文処理：API側でトランザクション管理（フロントは単一API呼び出し）

## パフォーマンス要件

- 詳細データロード：2秒以内
- キャンセル処理：3秒以内
- 再注文処理：3秒以内

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

- 認証トークンを使用したAPI呼び出し
- 注文IDによるデータアクセス制御（サーバーサイド）
- キャンセル処理時の確認ダイアログ表示

## 備考

- ステータスの色分けはOrderStatusBGColorHelper mixinで管理
- 商品画像が存在しない場合はデフォルト画像を表示
- additionalフィールドから商品属性（サイズ、色等）を抽出して表示

---

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

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

### 推奨読解順序

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

まず、APIレスポンスのデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | order_detail_model.dart | `lib/data_model/order_model/order_detail_model.dart` | OrderDetail、Items、BillingAddress、Paymentの構造を理解 |

**読解のコツ**: GraphQlBaseErrorModelを継承しており、エラーハンドリングの基本構造も把握できる。

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

処理の起点となるウィジェットを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | order_detail.dart | `lib/screens/order_detail/view/order_detail.dart` | StatefulWidgetの構造、initStateでのBloc初期化 |

**主要処理フロー**:
1. **37-40行目**: initStateでOrderDetailBlocを取得し、OrderDetailFetchDataEventを発行
2. **59-88行目**: BlocConsumerでstateの変化を監視
3. **61-82行目**: listenerでキャンセル結果と再注文結果を処理
4. **91-124行目**: buildContainerでstate別のUI切り替え

#### Step 3: BLoCパターンを理解する

状態管理のBLoCパターンを読み解く。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order_detail_event.dart | `lib/screens/order_detail/bloc/order_detail_event.dart` | 4つのイベント（Fetch/Cancel/Loading/ReOrder） |
| 3-2 | order_detail_state.dart | `lib/screens/order_detail/bloc/order_detail_state.dart` | 各イベントに対応するState定義 |
| 3-3 | order_detail_bloc.dart | `lib/screens/order_detail/bloc/order_detail_bloc.dart` | イベントハンドリングとstateのemit |

**主要処理フロー**:
- **order_detail_bloc.dart 26-40行目**: OrderDetailFetchDataEvent処理
- **order_detail_bloc.dart 41-54行目**: CancelOrderEvent処理
- **order_detail_bloc.dart 58-70行目**: ReOrderEvent処理

#### Step 4: リポジトリ層を理解する

API呼び出しの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | order_detail_repository.dart | `lib/screens/order_detail/bloc/order_detail_repository.dart` | 3つのAPIメソッド（getOrderDetails/cancelOrder/reOrderCustomerOrder） |

**主要処理フロー**:
- **25-35行目**: getOrderDetailsでApiClient.getOrderDetail呼び出し
- **39-49行目**: cancelOrderでApiClient.cancelOrder呼び出し
- **52-62行目**: reOrderCustomerOrderでApiClient.reOrderCustomerOrder呼び出し

#### Step 5: UI表示を理解する

注文詳細画面の表示ロジックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | order_detail_tile.dart | `lib/screens/order_detail/widgets/order_detail_tile.dart` | 詳細表示の各セクション、キャンセル・再注文ボタン、遷移処理 |

**主要処理フロー**:
- **74-185行目**: キャンセルボタンの表示条件とダイアログ処理
- **231-251行目**: 再注文ボタンと処理
- **257-488行目**: 商品一覧の表示
- **608-625行目**: 請求書・配送・返金詳細ボタンの表示条件
- **649-675行目**: shipmentInvoiceDetailsで遷移ボタン実装

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

```
OrderDetailScreen (Widget)
    │
    ├─ OrderDetailBloc
    │      │
    │      └─ OrderDetailRepositoryImp
    │             │
    │             ├─ ApiClient.getOrderDetail()
    │             ├─ ApiClient.cancelOrder()
    │             └─ ApiClient.reOrderCustomerOrder()
    │
    ├─ OrderDetailFetchDataState / CancelOrderState / ReOrderState
    │      │
    │      └─ OrderDetail / BaseModel / AddToCartModel
    │
    └─ OrderDetailTile (Widget)
           │
           ├─ ShippingAndPaymentInfo (Widget)
           │
           └─ Navigator.pushNamed
                  │
                  ├─ → InvoiceScreen
                  ├─ → OrderShipmentsScreen
                  └─ → OrderRefundScreen
```

### データフロー図

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

orderId ───▶ OrderDetailFetchDataEvent ───▶ OrderDetailBloc
   │                                              │
   │                                              ▼
   │                                    OrderDetailRepository
   │                                              │
   │                                              ▼
   │                                      ApiClient (GraphQL)
   │                                              │
   │                                              ▼
   │                                        OrderDetail
   │                                              │
   │                                              ▼
   └─────────────────────────────── OrderDetailFetchDataState ───▶ UI更新


[キャンセル処理]
ボタン押下 → ダイアログ確認 → CancelOrderEvent → cancelOrder API → CancelOrderState → 画面戻る

[再注文処理]
ボタン押下 → ReOrderEvent → reOrderCustomerOrder API → ReOrderState → カート画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| order_detail.dart | `lib/screens/order_detail/view/order_detail.dart` | ソース | メイン画面ウィジェット |
| order_detail_bloc.dart | `lib/screens/order_detail/bloc/order_detail_bloc.dart` | ソース | 状態管理BLoC |
| order_detail_event.dart | `lib/screens/order_detail/bloc/order_detail_event.dart` | ソース | イベント定義 |
| order_detail_state.dart | `lib/screens/order_detail/bloc/order_detail_state.dart` | ソース | 状態定義 |
| order_detail_repository.dart | `lib/screens/order_detail/bloc/order_detail_repository.dart` | ソース | リポジトリ層 |
| order_detail_tile.dart | `lib/screens/order_detail/widgets/order_detail_tile.dart` | ソース | 詳細表示UI |
| shipping_payment_info.dart | `lib/screens/order_detail/widgets/shipping_payment_info.dart` | ソース | 配送・支払い情報UI |
| order_detail_loader.dart | `lib/screens/order_detail/widgets/order_detail_loader.dart` | ソース | ローディング表示 |
| order_detail_model.dart | `lib/data_model/order_model/order_detail_model.dart` | ソース | データモデル |
| index.dart | `lib/screens/order_detail/utils/index.dart` | ソース | エクスポート定義 |
