# 機能設計書 17-注文交換管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおける注文交換管理機能の設計を記載したものである。注文に対する交換処理（商品の返品と代替品送付）の管理機能について、処理フロー、データ構造、ビジネスルールを定義する。

### 本機能の処理概要

注文交換管理機能は、ECサイトにおける商品交換処理を一元管理するための機能である。

**業務上の目的・背景**：ECサイトにおいて、サイズ違い・色違い等の理由による商品交換は一般的な顧客対応である。本機能は、元商品の返品と代替品の送付を一連のプロセスとして管理し、差額計算・追加支払い・返金等を適切に処理する。

**機能の利用シーン**：
- 顧客が商品交換を申請する場面
- 管理者が交換依頼を確認・承認する場面
- 代替品を発送する場面
- 差額の追加支払い・返金を処理する場面
- 交換をキャンセルする場面

**主要な処理内容**：
1. 交換（OrderExchange）の作成・取得・更新・削除
2. 交換アイテム（OrderExchangeItem）の管理
3. 交換に紐づく返品の管理
4. 差額（difference_due）の計算・管理
5. バックオーダー許可フラグの管理

**関連システム・外部連携**：
- 注文モジュール：注文との紐付け
- 返品モジュール：交換に伴う返品
- フルフィルメントモジュール：代替品配送
- 支払いモジュール：差額支払い・返金処理
- 在庫モジュール：バックオーダー管理

**権限による制御**：
- 交換の作成・承認・キャンセルは管理者権限を持つユーザーのみ実行可能
- 顧客は自身の注文に対する交換申請のみ可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | 交換作成画面 | 主画面 | 交換リクエストの作成 |
| 43 | 注文詳細画面 | 参照画面 | 交換履歴の表示 |

## 機能種別

CRUD操作 / 状態管理 / ワークフロー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| order_id | string | Yes | 注文ID | 有効な注文IDであること |
| return_items | ReturnItemInput[] | Yes | 返品アイテム | 1件以上必須 |
| additional_items | ExchangeItemInput[] | Yes | 追加アイテム（代替品） | 1件以上必須 |
| difference_due | BigNumber | No | 差額 | 自動計算または手動設定 |
| allow_backorder | boolean | No | バックオーダー許可 | デフォルトfalse |
| no_notification | boolean | No | 通知抑制フラグ | - |
| created_by | string | No | 作成者ID | - |
| metadata | object | No | メタデータ | JSON形式 |

### ExchangeItemInput

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| item_id | string | Yes | 商品バリアントID | 有効なバリアントIDであること |
| quantity | number | Yes | 数量 | 1以上 |
| note | string | No | メモ | - |

### 入力データソース

- 管理画面：交換申請の作成
- 顧客画面：交換リクエストの送信

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | string | 交換ID（prefix: oexc） |
| order_id | string | 注文ID |
| order_version | number | 注文バージョン |
| display_id | number | 表示用ID（自動採番） |
| difference_due | BigNumber | 差額（正:追加支払い、負:返金） |
| allow_backorder | boolean | バックオーダー許可フラグ |
| created_by | string | 作成者ID |
| canceled_at | Date | キャンセル日時 |
| additional_items | OrderExchangeItem[] | 追加アイテム |
| return | Return | 紐づく返品 |
| shipping_methods | OrderShipping[] | 配送方法 |
| transactions | OrderTransaction[] | トランザクション |

### 出力先

- データベース：order_exchange、order_exchange_item、returnテーブル
- API応答：OrderExchangeDTO形式

## 処理フロー

### 処理シーケンス

```
1. 交換作成リクエスト受信
   └─ order_id、return_items、additional_items等を含むリクエストを受信

2. 注文存在確認・バージョン取得
   └─ 対象注文の存在確認とバージョン取得

3. 返品の作成
   └─ Returnレコードを作成
   └─ ReturnItemレコードを作成

4. 交換の作成
   └─ OrderExchangeレコードを作成（return_idと紐付け）
   └─ OrderChangeを作成

5. 交換アイテムの作成
   └─ OrderExchangeItemレコードを作成
   └─ OrderChangeActionを追加

6. 差額の計算
   └─ 追加アイテム合計 - 返品アイテム合計 = difference_due

7. 変更の確認
   └─ confirmOrderChangeで変更を確定

8. 後続処理
   └─ difference_due > 0: 追加支払い要求
   └─ difference_due < 0: 返金処理
   └─ 代替品発送
```

### フローチャート

```mermaid
flowchart TD
    A[交換作成リクエスト] --> B[注文存在確認]
    B --> C{注文が存在?}
    C -->|No| D[エラー返却]
    C -->|Yes| E[Return作成]
    E --> F[OrderExchange作成]
    F --> G[OrderExchangeItem作成]
    G --> H[差額計算]
    H --> I[OrderChange作成]
    I --> J[confirmOrderChange]
    J --> K{difference_due?}
    K -->|正| L[追加支払い要求]
    K -->|負| M[返金処理]
    K -->|0| N[代替品発送のみ]
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-17-01 | 返品連携必須 | 交換は必ず返品（Return）と紐付けられる | 交換作成時 |
| BR-17-02 | 差額計算 | 追加アイテム金額 - 返品アイテム金額 = difference_due | 交換作成時 |
| BR-17-03 | バックオーダー | allow_backorder=trueの場合、在庫がなくても交換可能 | 交換作成時 |
| BR-17-04 | カスケード削除 | OrderExchange削除時はadditional_items、transactionsも削除 | 削除時 |

### 計算ロジック

```
difference_due = SUM(additional_item_total) - SUM(return_item_refund)

※ 各アイテムのtotal計算にはtax_lines、adjustmentsを考慮
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 交換作成 | return | INSERT | 紐づく返品の作成 |
| 交換作成 | return_item | INSERT | 返品アイテムの作成 |
| 交換作成 | order_exchange | INSERT | 交換レコードの作成 |
| 交換作成 | order_exchange_item | INSERT | 交換アイテムの作成 |
| 交換作成 | order_change | INSERT | 注文変更の作成 |
| 交換キャンセル | order_exchange | UPDATE | canceled_at更新 |

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

#### order_exchange

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: oexc） | 主キー |
| INSERT | order_id | 対象注文ID | 外部キー |
| INSERT | order_version | 注文の現在バージョン | 整数 |
| INSERT | display_id | 自動採番 | 表示用 |
| INSERT | difference_due | 計算された差額 | BigNumber |
| INSERT | allow_backorder | リクエストのallow_backorder | デフォルトfalse |
| INSERT | created_by | リクエストのcreated_by | nullable |
| INSERT | return_id | 作成された返品ID | 外部キー |
| UPDATE (cancel) | canceled_at | 現在日時 | - |

#### order_exchange_item

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | id | 自動生成（prefix: oexcitem） | 主キー |
| INSERT | exchange_id | 親の交換ID | 外部キー |
| INSERT | item_id | 注文明細ID（追加アイテム） | 外部キー |
| INSERT | quantity | リクエストのquantity | BigNumber |
| INSERT | note | リクエストのnote | nullable |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | MedusaError | 指定されたorder_idの注文が存在しない | 有効な注文IDを指定 |
| INVALID_DATA | MedusaError | 返品アイテムまたは追加アイテムが空 | 1件以上のアイテムを指定 |
| NOT_ALLOWED | MedusaError | 在庫不足かつallow_backorder=false | allow_backorderをtrueにするか在庫を確保 |
| NOT_ALLOWED | MedusaError | 既にキャンセルされた交換を操作 | キャンセル済み交換は操作不可 |

### リトライ仕様

データベース操作はトランザクション内で実行されるため、失敗時は自動ロールバックされる。

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

- `@InjectTransactionManager`デコレータにより、交換作成・キャンセル処理はトランザクション内で実行
- 交換作成時はReturn、ReturnItem、OrderExchange、OrderExchangeItem、OrderChange等が同一トランザクション内で作成
- 処理失敗時は全ての変更がロールバックされる

## パフォーマンス要件

- 交換作成：500ms以内
- 交換一覧取得：100件以下で500ms以内
- インデックス：order_id、return_idにインデックス設定

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

- 交換の作成・承認・キャンセルは認証済み管理者のみ実行可能
- 差額情報・決済情報は監査ログに記録
- 顧客は自身の注文に関連する交換のみ参照可能

## 備考

- 交換は返品（Return）と1:1の関係を持つ
- difference_dueが正の場合は顧客からの追加支払いが必要
- difference_dueが負の場合は顧客への返金が必要
- allow_backorderにより在庫がなくても交換を受け付けることが可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | exchange.ts | `packages/modules/order/src/models/exchange.ts` | OrderExchangeエンティティ、difference_due/allow_backorder/order_versionプロパティ、return/additional_itemsリレーション |
| 1-2 | exchange-item.ts | `packages/modules/order/src/models/exchange-item.ts` | OrderExchangeItemエンティティ、quantity/noteプロパティ |

**読解のコツ**:
- **9-18行目 (exchange.ts)**: order_version、difference_due、allow_backorder等の主要プロパティ
- **19-46行目 (exchange.ts)**: order、return、additional_items、shipping_methods、transactionsリレーション
- **48-50行目 (exchange.ts)**: カスケード削除の設定

#### Step 2: サービス層の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | 632-696行：retrieveOrderExchange、listOrderExchanges、listAndCountOrderExchangesメソッド |
| 2-2 | create-exchange.ts | `packages/modules/order/src/services/actions/create-exchange.ts` | 交換作成の詳細ロジック |
| 2-3 | cancel-exchange.ts | `packages/modules/order/src/services/actions/cancel-exchange.ts` | 交換キャンセルの詳細ロジック |

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

```
createExchange (actions/create-exchange.ts)
    ├─ returnService_.create（返品作成）
    ├─ returnItemService_.create（返品アイテム作成）
    ├─ orderExchangeService_.create
    ├─ orderExchangeItemService_.create
    ├─ 差額計算
    ├─ createOrderChange_
    └─ confirmOrderChange

cancelExchange (actions/cancel-exchange.ts)
    ├─ createOrderChange_
    ├─ orderExchangeService_.update (canceled_at)
    └─ confirmOrderChange
```

### データフロー図

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

CreateExchangeDTO ───────▶ createExchange ────────────▶ return テーブル
       │                        │
       │                        ├─▶ returnItemService_ ─▶ return_item テーブル
       │                        │
       │                        ├─▶ exchangeService_ ───▶ order_exchange テーブル
       │                        │
       │                        ├─▶ exchangeItemService_▶ order_exchange_item テーブル
       │                        │
       v                        v
 return_items,            差額計算                      OrderExchangeDTO
 additional_items         difference_due
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| exchange.ts | `packages/modules/order/src/models/exchange.ts` | ソース | OrderExchangeエンティティ定義 |
| exchange-item.ts | `packages/modules/order/src/models/exchange-item.ts` | ソース | OrderExchangeItemエンティティ定義 |
| order-module-service.ts | `packages/modules/order/src/services/order-module-service.ts` | ソース | サービス層（retrieve/list） |
| create-exchange.ts | `packages/modules/order/src/services/actions/create-exchange.ts` | ソース | 交換作成アクション |
| cancel-exchange.ts | `packages/modules/order/src/services/actions/cancel-exchange.ts` | ソース | 交換キャンセルアクション |
| return.ts | `packages/modules/order/src/models/return.ts` | ソース | 返品エンティティ（紐付け先） |
