# 帳票設計書 2-Shipment（出荷伝票）

## 概要

本ドキュメントは、ECモバイルアプリにおける出荷伝票（Shipment）帳票の設計仕様を定義するものである。注文に対して発行された出荷情報を画面上に表示する機能について記述する。

### 本帳票の処理概要

本帳票は、顧客が注文詳細画面から出荷情報を確認するための機能を提供する。注文に紐づく出荷一覧を取得し、各出荷の追跡番号と商品明細を整形して画面表示する。

**業務上の目的・背景**：ECサイトにおいて、顧客が注文した商品の配送状況を追跡することは購入体験の重要な要素である。本帳票は、出荷IDと追跡番号を提供し、顧客が配送業者のトラッキングシステムで荷物の現在位置を確認できるようにする。これにより、「商品はいつ届くのか」という顧客の最も多い問い合わせに対応できる。

**帳票の利用シーン**：顧客が注文履歴から特定の注文を選択し、その出荷状況を確認する場面で利用される。商品発送後の配送追跡、複数回に分かれた出荷の確認、届かない荷物の調査などに使用される。

**主要な出力内容**：
1. 追跡番号（Tracking Number）
2. 出荷ID（Shipment ID）
3. 出荷明細（SKU、商品名、数量）
4. 配送・支払い情報

**帳票の出力タイミング**：注文詳細画面において、出荷情報セクションを選択またはタップした際に、GraphQL APIを通じてデータを取得し画面に表示する。

**帳票の利用者**：出荷状況を確認したい一般顧客（エンドユーザー）。

## 帳票種別

出荷伝票（Shipment）- 画面表示形式

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | 出荷詳細画面 | OrderShipmentsScreen（Flutter Widget） | 注文詳細画面から出荷セクションを選択 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | 画面表示（Flutter Widget） |
| 用紙サイズ | N/A（モバイルアプリ画面） |
| 向き | 縦（スクロール可能） |
| ファイル名 | N/A |
| 出力方法 | 画面レンダリング |
| 文字コード | UTF-8 |

### PDF固有設定

N/A（本帳票は画面表示のみ）

### Excel固有設定

N/A

## 帳票レイアウト

### レイアウト概要

出荷画面は、追跡情報と出荷明細部、配送・支払い情報部で構成される。スクロール可能なシングルカラムレイアウトを採用し、出荷が複数存在する場合は縦に並列表示される。

```
┌─────────────────────────────────────┐
│           AppBar（出荷）            │
├─────────────────────────────────────┤
│     追跡番号: XXXXX                 │
│     出荷 #ID                        │
│     ─────────────────               │
│     商品明細リスト                   │
│     - SKU / 商品名 / 数量           │
├─────────────────────────────────────┤
│     配送・支払い情報                 │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 追跡番号 | 配送業者の追跡番号 | ViewShipments.trackNumber | "Tracking Number " + 番号 |
| 2 | 出荷ID | 出荷の識別番号 | ViewShipments.id | "Shipment #" + ID |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | SKU | 商品SKUコード | ItemsModel.sku | 文字列 | 自動 |
| 2 | 商品名 | 商品の名称 | ItemsModel.name | 文字列 | 自動 |
| 3 | 数量 | 出荷数量 | ItemsModel.qty | 整数 | 自動 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 配送・支払い情報 | 注文の配送・支払い詳細 | orderDetailsModel | ShippingAndPaymentInfoウィジェット |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 注文ID | 対象注文の識別子 | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 出荷ID | APIレスポンス順（デフォルト） |

### 改ページ条件

N/A（画面スクロールにより全件表示）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| shipments | 出荷基本情報 | order_id = 指定注文ID |
| shipment_items | 出荷明細 | shipment_id = shipments.id |
| orders | 注文情報 | id = 指定注文ID |

### テーブル別参照項目詳細

#### shipments

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | 出荷ID | order_id一致 | - |
| track_number | 追跡番号 | - | 配送業者発行 |

#### shipment_items

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| id | 明細ID | shipment_id一致 | - |
| sku | SKU | - | - |
| name | 商品名 | - | - |
| qty | 数量 | - | - |

## 計算仕様

### 計算項目一覧

本帳票には計算項目は存在しない。すべての値はバックエンドから直接取得される。

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| - | - | - | 計算項目なし |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[注文詳細画面で出荷セクションを選択] --> B[OrderShipmentsScreen初期化]
    B --> C[OrderShipmentsBloc初期化]
    C --> D[OrderShipmentsFetchDataEventを発行]
    D --> E[OrderShipmentsRepositoryでAPI呼び出し]
    E --> F[GraphQL viewShipmentsクエリ実行]
    F --> G[ShipmentModelにパース]
    G --> H{データ取得成功?}
    H -->|Yes| I[OrderShipmentsListDataState.success発行]
    H -->|No| J[OrderShipmentsListDataState.fail発行]
    I --> K[shipmentsDetails()で画面レンダリング]
    J --> L[エラー状態表示]
    K --> M[追跡番号・出荷明細・配送支払い情報を表示]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | 出荷が存在しない | EmptyDataView表示 | 空データビューを表示 |
| 通信エラー | ネットワーク障害 | エラーメッセージ | 再試行またはオフライン対応 |
| APIエラー | サーバー側エラー | エラーメッセージ | エラーログ出力、再試行促進 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1注文あたり1〜数件の出荷 |
| 目標出力時間 | 2秒以内 |
| 同時出力数上限 | N/A（ユーザー単位で逐次処理） |

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

- 認証済みユーザーのみがアクセス可能（ログインセッション必須）
- 自身の注文に紐づく出荷のみ参照可能（他ユーザーの出荷は参照不可）
- GraphQL APIはHTTPS通信で保護
- 追跡番号は個人情報に該当する可能性があるため、適切なアクセス制御が必要

## 備考

- 本帳票はFlutterアプリ内での画面表示機能であり、PDFや印刷出力には対応していない
- 追跡番号は配送業者が発行した番号をそのまま表示
- ShippingAndPaymentInfoウィジェットで配送・支払い情報を共通表示
- 請求書帳票と比較して、価格情報は含まれず出荷に関する物流情報のみ

---

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

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

### 推奨読解順序

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

まず、出荷データのモデル構造を把握することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | shipment_model.dart | `lib/data_model/order_model/shipment_model.dart` | ShipmentModel、ViewShipments、ItemsModelの構造を理解。各フィールドがAPIレスポンスのどの部分に対応するか確認 |

**読解のコツ**: `@JsonSerializable()`アノテーションと`@JsonKey`でJSONとの対応付けを確認する。コメントアウトされたフィールド（price, total等）は現在未使用だが、将来の拡張候補。

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

処理の起点となる画面ウィジェットを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | shipments_details.dart | `lib/screens/order_shipping/shipments_details.dart` | OrderShipmentsScreenウィジェットの構造と状態管理を理解 |

**主要処理フロー**:
1. **18-22行目**: initState()でOrderShipmentsBlocを取得し、OrderShipmentsFetchDataEventを発行
2. **39-54行目**: BlocConsumerでStateを監視し、成功時にshipmentsDetails()を呼び出し
3. **57-83行目**: shipmentsDetails()で出荷データをUIにレンダリング
4. **106-150行目**: getShipments()で各出荷の明細をListView形式で表示

#### Step 3: BLoCパターンによる状態管理を理解する

Flutterの状態管理としてBLoCパターンを採用している。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order_shipments_bloc.dart | `lib/screens/order_shipping/bloc/order_shipments_bloc.dart` | イベントを受けてリポジトリを呼び出し、結果をStateとして発行する流れ |
| 3-2 | order_shipments_state.dart | `lib/screens/order_shipping/bloc/order_shipments_state.dart` | OrderShipmentsInitialState、OrderShipmentsListDataStateの定義 |

**主要処理フロー**:
- **23-35行目（bloc）**: mapEventToStateでOrderShipmentsFetchDataEventを処理し、成功/失敗に応じてStateを発行

#### Step 4: リポジトリ層とAPI通信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | order_shipments_repository.dart | `lib/screens/order_shipping/bloc/order_shipments_repository.dart` | ApiClient().getShipmentsList()の呼び出し |
| 4-2 | api_client.dart | `lib/services/api_client.dart` | 1388-1400行目：getShipmentsListメソッドでGraphQLクエリを実行 |
| 4-3 | mutation_query.dart | `lib/services/mutation_query.dart` | 1896-1926行目：viewShipmentsのGraphQLクエリ定義 |

**主要処理フロー**:
- **1388行目（api_client）**: getShipmentsList()でmutation.getShipmentsList()を実行
- **1896行目（mutation_query）**: GraphQLクエリでorderId指定して出荷データを取得

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

```
OrderShipmentsScreen (Widget)
    │
    ├─ initState()
    │      └─ OrderShipmentsBloc.add(OrderShipmentsFetchDataEvent)
    │
    ├─ BlocConsumer<OrderShipmentsBloc, OrderShipmentsBaseState>
    │      │
    │      └─ OrderShipmentsBloc.mapEventToState()
    │             └─ OrderShipmentsRepositoryImp.getShipmentsList()
    │                    └─ ApiClient.getShipmentsList()
    │                           └─ mutation.getShipmentsList() [GraphQL]
    │
    └─ shipmentsDetails()
           ├─ getShipments() [出荷リスト表示]
           │      ├─ 追跡番号表示
           │      ├─ 出荷ID表示
           │      └─ childData() [明細行表示]
           └─ ShippingAndPaymentInfo [共通ウィジェット]
```

### データフロー図

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

orderId ─────────▶ OrderShipmentsFetchDataEvent
                          │
                          ▼
                  OrderShipmentsBloc
                          │
                          ▼
                  OrderShipmentsRepositoryImp
                          │
                          ▼
                  ApiClient.getShipmentsList()
                          │
                          ▼
                  GraphQL viewShipments Query ────▶ Backend Server
                          │
                          ▼
                  ShipmentModel (JSON Parse)
                          │
                          ▼
                  OrderShipmentsListDataState.success
                          │
                          ▼
                  OrderShipmentsScreen.shipmentsDetails() ────▶ UI表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| shipments_details.dart | `lib/screens/order_shipping/shipments_details.dart` | ソース | 出荷画面のUI実装 |
| order_shipments_bloc.dart | `lib/screens/order_shipping/bloc/order_shipments_bloc.dart` | ソース | 状態管理BLoC |
| order_shipments_state.dart | `lib/screens/order_shipping/bloc/order_shipments_state.dart` | ソース | 状態定義 |
| order_shipments_event.dart | `lib/screens/order_shipping/bloc/order_shipments_event.dart` | ソース | イベント定義 |
| order_shipments_repository.dart | `lib/screens/order_shipping/bloc/order_shipments_repository.dart` | ソース | リポジトリ層 |
| shipment_model.dart | `lib/data_model/order_model/shipment_model.dart` | ソース | データモデル定義 |
| api_client.dart | `lib/services/api_client.dart` | ソース | API通信クライアント |
| mutation_query.dart | `lib/services/mutation_query.dart` | ソース | GraphQLクエリ定義 |
| index.dart | `lib/screens/order_shipping/utils/index.dart` | ソース | エクスポート定義 |
