# 機能設計書 22-注文一覧表示

## 概要

本ドキュメントは、Shopwareストアフロントにおける注文一覧表示機能の設計を記述したものである。本機能は、顧客が過去に行った注文の履歴を一覧形式で表示し、注文状況の確認や詳細情報へのアクセスを可能にする。

### 本機能の処理概要

注文一覧表示機能は、ログイン済み顧客のマイアカウント画面において、過去の注文履歴をページネーション付きで表示する機能を提供する。

**業務上の目的・背景**：ECサイトにおいて、顧客が自身の注文履歴を確認できることは基本的かつ重要な機能である。注文状況の追跡、過去の購入内容の確認、再注文の検討、返品・交換の準備など、多くの業務シーンで活用される。顧客自身がセルフサービスで注文情報を確認できることで、カスタマーサポートへの問い合わせ削減にも寄与する。

**機能の利用シーン**：
- 注文後に配送状況を確認したい場合
- 過去に購入した商品を再度購入したい場合
- 支払い状況を確認したい場合
- 請求書や納品書をダウンロードしたい場合
- 注文をキャンセルしたい場合
- デジタル商品をダウンロードしたい場合

**主要な処理内容**：
1. ログイン顧客の注文履歴をデータベースから取得
2. 注文日時の降順でソートして表示
3. ページネーション処理（1ページあたり10件）
4. 各注文の概要情報（注文番号、日付、金額、ステータス）を表示
5. 関連情報（明細、住所、支払い方法、配送方法、ドキュメント）の取得と表示

**関連システム・外部連携**：
- AbstractOrderRoute: 注文データ取得API
- GenericPageLoader: 共通ページ要素（ヘッダー、フッター等）の読み込み
- イベントディスパッチャー: OrderRouteRequestEvent、AccountOrderPageLoadedEventの発火

**権限による制御**：
- ログイン必須（LOGIN_REQUIRED属性）
- ゲスト顧客もアクセス可能（LOGIN_REQUIRED_ALLOW_GUEST属性）
- ゲスト顧客の場合はdeepLinkCodeによる認証が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 21 | 注文履歴ページ | 主画面 | 過去の注文一覧表示（AccountOrderController::orderOverview） |
| 16 | アカウントホームページ | 参照画面 | 最近の注文の表示 |
| 41 | 注文一覧（管理画面） | 参照画面 | 注文の一覧表示・ステータス管理 |
| 67 | インポート/エクスポート | 補助機能 | 注文データの一括入出力 |

## 機能種別

CRUD操作（Read） / データ表示 / ページネーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p | int | No | ページ番号（デフォルト: 1） | 正の整数 |
| deepLinkCode | string | No | ゲスト注文アクセス用コード | 文字列 |
| email | string | No | ゲスト認証用メールアドレス | メール形式 |
| zipcode | string | No | ゲスト認証用郵便番号 | 文字列 |

### 入力データソース

- HTTPリクエストパラメータ（Query）
- SalesChannelContext（顧客情報、セッション情報）
- URLルートパラメータ（deepLinkCode）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | AccountOrderPage | 注文一覧ページオブジェクト |
| page.orders | EntitySearchResult<OrderCollection> | 注文コレクション（ページネーション付き） |
| page.deepLinkCode | string | ゲスト用ディープリンクコード |
| page.metaInformation | MetaInformation | SEOメタ情報 |

#### 注文データの詳細項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| order.orderNumber | string | 注文番号 |
| order.orderDateTime | DateTimeInterface | 注文日時 |
| order.amountTotal | float | 注文合計金額 |
| order.stateMachineState | StateMachineStateEntity | 注文ステータス |
| order.primaryOrderTransaction | OrderTransactionEntity | プライマリ決済トランザクション |
| order.primaryOrderDelivery | OrderDeliveryEntity | プライマリ配送情報 |
| order.lineItems | OrderLineItemCollection | 注文明細 |
| order.currency | CurrencyEntity | 通貨情報 |
| order.documents | DocumentCollection | 関連ドキュメント（請求書等） |

### 出力先

- HTMLレスポンス（Twigテンプレート: `@Storefront/storefront/page/account/order-history/index.html.twig`）

## 処理フロー

### 処理シーケンス

```
1. orderOverview（GET/POST /account/order）
   └─ 顧客ログイン状態の確認
   └─ AccountOrderPageLoader.loadを呼び出し
      └─ GenericPageLoaderでベースページを読み込み
      └─ メタ情報を設定（robots: noindex,follow）
      └─ createCriteriaで検索条件を構築
      └─ OrderRouteRequestEventを発火
      └─ AbstractOrderRoute.loadで注文を取得
      └─ AccountOrderPageLoadedEventを発火
   └─ AccountOrderPageLoadedHookを発火
   └─ order-history/index.html.twigをレンダリング
```

### フローチャート

```mermaid
flowchart TD
    A[注文一覧画面アクセス] --> B{顧客ログイン済み?}
    B -->|No| C{deepLinkCodeあり?}
    C -->|No| D[CustomerNotLoggedInException]
    C -->|Yes| E[ゲスト認証処理]
    B -->|Yes| F[AccountOrderPageLoader.load]

    E --> G{認証成功?}
    G -->|No| H[ゲストログインページへリダイレクト]
    G -->|Yes| F

    F --> I[GenericPageLoader.load]
    I --> J[メタ情報設定]
    J --> K[検索条件構築]
    K --> L[OrderRouteRequestEvent発火]
    L --> M[AbstractOrderRoute.load]
    M --> N[注文データ取得]
    N --> O[AccountOrderPageLoadedEvent発火]
    O --> P[AccountOrderPage返却]
    P --> Q[Twigレンダリング]
    Q --> R[HTMLレスポンス]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-22-01 | ログイン必須 | 注文一覧はログイン済み顧客のみ閲覧可能 | 常時 |
| BR-22-02 | 顧客所有確認 | 表示される注文は当該顧客が注文したもののみ | 常時 |
| BR-22-03 | ゲストアクセス | ゲスト顧客はdeepLinkCode+email+zipcodeで認証 | deepLinkCode指定時 |
| BR-22-04 | 表示順序 | 注文日時の降順で表示 | 常時 |
| BR-22-05 | ページネーション | 1ページあたり10件表示 | 常時 |
| BR-22-06 | ステータス表示 | 注文ステータス、支払いステータス、配送ステータスを表示 | 常時 |

### 計算ロジック

#### ページネーション計算

```
offset = (page - 1) * DEFAULT_LIMIT
limit = DEFAULT_LIMIT (10)
totalCountMode = TOTAL_COUNT_MODE_EXACT
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 注文一覧取得 | order | SELECT | 顧客の注文一覧を取得 |
| トランザクション取得 | order_transaction | SELECT | 関連する決済トランザクション |
| 配送情報取得 | order_delivery | SELECT | 関連する配送情報 |
| 明細取得 | order_line_item | SELECT | 注文明細 |
| ドキュメント取得 | document | SELECT | 関連ドキュメント（請求書等） |
| 住所取得 | order_address | SELECT | 注文に紐づく住所 |

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

#### order

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | orderCustomer.customerId = {顧客ID} | ログイン顧客の場合 |
| SELECT | * | deepLinkCode = {deepLinkCode} | ゲスト顧客の場合 |

#### Association（関連テーブル）

以下のAssociationがCriteriaに設定される：
- primaryOrderTransaction.paymentMethod
- primaryOrderTransaction.stateMachineState
- primaryOrderDelivery.shippingMethod
- primaryOrderDelivery.stateMachineState
- deliveries.shippingMethod
- orderCustomer.customer
- lineItems
- lineItems.cover
- lineItems.downloads.media
- addresses
- currency
- stateMachineState
- documents.documentType
- documents.documentMediaFile
- documents.documentA11yMediaFile

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CUSTOMER_NOT_LOGGED_IN | 認証エラー | 未ログインかつdeepLinkCodeなし | ログインページへリダイレクト |
| GUEST_NOT_AUTHENTICATED | 認証エラー | ゲスト認証情報不足 | ゲストログインページへリダイレクト |
| WRONG_GUEST_CREDENTIALS | 認証エラー | ゲスト認証情報不正 | エラーメッセージ表示 |
| CUSTOMER_AUTH_THROTTLED | 認証エラー | 認証試行回数超過 | 待機時間を表示 |

### リトライ仕様

認証エラーの場合、ユーザーに再入力を促す。スロットリングが発生した場合は、waitTimeを表示して待機を促す。

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

本機能は参照のみのため、トランザクション制御は不要。DALの読み取り処理として実行される。

## パフォーマンス要件

- ページ表示: 1秒以内
- 注文件数が多い場合でもページネーションにより一定のパフォーマンスを維持
- Associationの最適化により必要なデータのみ取得

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

- ログイン認証必須（LOGIN_REQUIRED属性）
- 顧客IDによるアクセス制御（他顧客の注文は閲覧不可）
- ゲスト認証はdeepLinkCode + email + zipcodeの組み合わせで検証
- 認証試行のスロットリング（ブルートフォース攻撃対策）
- robots: noindex,follow（検索エンジンへのインデックス防止）
- XmlHttpRequest対応（AJAX呼び出し可能）

## 備考

- v6.8.0.0以降では、transactions/deliveriesの関連取得が廃止され、primaryOrderTransaction/primaryOrderDeliveryに統一される予定
- XmlHttpRequestとしても動作可能で、ページの部分更新に対応
- NO_STORE属性により、ブラウザキャッシュは無効化される

---

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

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

### 推奨読解順序

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

まず、注文一覧で扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OrderEntity.php | `src/Core/Checkout/Order/OrderEntity.php` | 注文エンティティの構造、プロパティ（orderNumber, orderDateTime, amountTotal, stateMachineState等） |
| 1-2 | AccountOrderPage.php | `src/Storefront/Page/Account/Order/AccountOrderPage.php` | 注文一覧ページのデータ構造 |
| 1-3 | OrderLineItemEntity.php | `src/Core/Checkout/Order/Aggregate/OrderLineItem/OrderLineItemEntity.php` | 注文明細エンティティ |

**読解のコツ**: OrderEntityは多くのAssociation（関連エンティティ）を持つ。primaryOrderTransaction、primaryOrderDeliveryなどのプライマリ参照と、transactions、deliveriesなどのコレクション参照の違いを理解することが重要。

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

処理の起点となるコントローラーを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AccountOrderController.php | `src/Storefront/Controller/AccountOrderController.php` | 注文一覧のエントリーポイント |

**主要処理フロー**:
1. **76-102行目**: `orderOverview`メソッド - 注文一覧表示処理
2. **97行目**: AccountOrderPageLoader.load呼び出し
3. **99行目**: AccountOrderPageLoadedHook発火
4. **101行目**: Twigテンプレートレンダリング

#### Step 3: ページローダーを理解する

注文一覧ページの読み込み処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AccountOrderPageLoader.php | `src/Storefront/Page/Account/Order/AccountOrderPageLoader.php` | ページデータの組み立て |

**主要処理フロー**:
- **45-67行目**: `load`メソッド - ページデータの読み込み
- **47-49行目**: ログイン状態チェック
- **56行目**: getOrdersで注文データ取得
- **60行目**: deepLinkCodeの設定
- **91-110行目**: `getOrders`メソッド - 注文データ取得処理
- **112-157行目**: `createCriteria`メソッド - 検索条件構築

#### Step 4: Store-APIルートを理解する

注文取得に使用されるAPIルートを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractOrderRoute.php | `src/Core/Checkout/Order/SalesChannel/AbstractOrderRoute.php` | 注文取得の抽象クラス |

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

```
AccountOrderController
    │
    └─ orderOverview (GET/POST /account/order)
           ├─ AccountOrderPageLoader.load
           │      ├─ GenericPageLoader.load
           │      ├─ setMetaInformation
           │      ├─ getOrders
           │      │      ├─ createCriteria
           │      │      │      └─ Criteria構築（Association設定、ソート、ページネーション）
           │      │      ├─ OrderRouteRequestEvent dispatch
           │      │      └─ AbstractOrderRoute.load
           │      └─ AccountOrderPageLoadedEvent dispatch
           ├─ AccountOrderPageLoadedHook
           └─ renderStorefront (order-history/index.html.twig)
```

### データフロー図

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

HTTPリクエスト ─────────────────┬──────────────────────────────────► 注文一覧HTML
(GET /account/order)           │
                               ▼
                    ┌─────────────────────┐
                    │ AccountOrder        │
                    │ Controller          │
                    │ ::orderOverview     │
                    └─────────┬───────────┘
                              │
                              ▼
                    ┌─────────────────────┐
                    │ AccountOrderPage    │
                    │ Loader              │
                    └─────────┬───────────┘
                              │
                              ▼
                    ┌─────────────────────┐
                    │ AbstractOrderRoute  │◄──── order
                    │ .load               │      order_transaction
                    └─────────┬───────────┘      order_delivery
                              │                  order_line_item
                              │                  document
                              ▼
                    ┌─────────────────────┐
                    │ AccountOrderPage    │
                    │ (ViewModel)         │
                    └─────────┬───────────┘
                              │
                              ▼
                    ┌─────────────────────┐
                    │ Twig Template       │
                    │ (order-history/     │─────────────────────────► HTMLレスポンス
                    │  index.html.twig)   │
                    └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AccountOrderController.php | `src/Storefront/Controller/AccountOrderController.php` | ソース | コントローラー（エントリーポイント） |
| AccountOrderPageLoader.php | `src/Storefront/Page/Account/Order/AccountOrderPageLoader.php` | ソース | ページデータ読み込み |
| AccountOrderPage.php | `src/Storefront/Page/Account/Order/AccountOrderPage.php` | ソース | ページビューモデル |
| OrderEntity.php | `src/Core/Checkout/Order/OrderEntity.php` | ソース | 注文エンティティ |
| AbstractOrderRoute.php | `src/Core/Checkout/Order/SalesChannel/AbstractOrderRoute.php` | ソース | 注文取得API抽象クラス |
| OrderRouteRequestEvent.php | `src/Storefront/Event/RouteRequest/OrderRouteRequestEvent.php` | ソース | 注文取得イベント |
| AccountOrderPageLoadedEvent.php | `src/Storefront/Page/Account/Order/AccountOrderPageLoadedEvent.php` | ソース | ページ読み込み完了イベント |
| AccountOrderPageLoadedHook.php | `src/Storefront/Page/Account/Order/AccountOrderPageLoadedHook.php` | ソース | ページ読み込み完了フック |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/account/order-history/index.html.twig` | テンプレート | 注文一覧表示テンプレート |
