# 機能設計書 45-請求書表示

## 概要

本ドキュメントは、ECモバイルアプリケーションにおける請求書表示機能の設計仕様を定義する。注文に対する請求書情報（商品明細、価格、税金等）を表示する機能である。

### 本機能の処理概要

この機能は、注文詳細画面から遷移し、該当注文の請求書情報を詳細に表示する。請求書番号、商品明細、価格内訳、配送先・支払い情報などを確認できる。

**業務上の目的・背景**：ECサイトにおいて、請求書情報の確認は経理処理や領収書代わりとして重要である。企業ユーザーの経費精算、個人ユーザーの家計管理、税務申告用の記録として利用される。正確な請求情報を提供することで、取引の透明性を確保する。

**機能の利用シーン**：ユーザーが注文詳細画面で「請求書詳細」ボタンをタップした際に利用される。経費精算の確認、支払い金額の詳細確認、税額の確認などに使用される。

**主要な処理内容**：
1. 注文IDに基づく請求書データの取得
2. 請求書番号と商品明細の表示
3. 価格詳細（小計、配送料、税金、合計）の表示
4. 配送先・支払い情報の表示

**関連システム・外部連携**：バックエンドのBagisto GraphQL APIと連携し、請求書データを取得する。

**権限による制御**：ログイン済みユーザーのみがアクセス可能。ユーザーは自身の注文の請求書のみを閲覧できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | 請求書詳細画面 | 主画面 | 注文の請求書情報表示（商品、価格、税金の明細） |
| 18 | 注文詳細画面 | 参照元画面 | 請求書詳細ボタンから遷移 |

## 機能種別

データ取得 / 詳細表示

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- 画面遷移引数：OrderDetailモデル（orderIdを含む）
- ユーザーセッション：認証トークン（SharedPreferencesから取得）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| viewInvoices[].id | int | 請求書ID |
| viewInvoices[].items[].sku | String | 商品SKU |
| viewInvoices[].items[].name | String | 商品名 |
| viewInvoices[].items[].qty | int | 数量 |
| viewInvoices[].items[].formattedPrice.price | String | 単価 |
| viewInvoices[].items[].formattedPrice.baseTotal | String | 小計 |
| viewInvoices[].items[].formattedPrice.taxAmount | String | 税額 |
| viewInvoices[].items[].formattedPrice.total | String | 合計 |
| viewInvoices[].formattedPrice.subTotal | String | 請求書小計 |
| viewInvoices[].formattedPrice.shippingAmount | String | 配送料 |
| viewInvoices[].formattedPrice.taxAmount | String | 税額合計 |
| viewInvoices[].formattedPrice.grandTotal | String | 総合計 |

### 出力先

- 画面表示：InvoiceScreenウィジェットによる請求書詳細表示

## 処理フロー

### 処理シーケンス

```
1. 画面初期化（initState）
   └─ OrderInvoiceBlocを取得し、OrderInvoiceFetchDataEventを発行
2. API呼び出し
   └─ OrderInvoiceRepositoryImpがApiClient経由でGraphQL APIを呼び出し
3. レスポンス処理
   └─ InvoicesModelにデシリアライズ
4. 状態更新
   └─ OrderInvoiceListDataStateをemitしてUI更新
5. 請求書表示
   └─ 請求書番号、商品明細、価格詳細、配送・支払い情報を表示
```

### フローチャート

```mermaid
flowchart TD
    A[注文詳細画面] --> B{qtyInvoiced > 0?}
    B -->|Yes| C[請求書ボタン表示]
    B -->|No| D[請求書ボタン非表示]
    C --> E[請求書ボタン押下]
    E --> F[InvoiceScreen遷移]
    F --> G[OrderInvoiceFetchDataEvent発行]
    G --> H[getInvoicesList API呼び出し]
    H --> I{レスポンス成功?}
    I -->|Yes| J[InvoicesModel生成]
    I -->|No| K[エラー表示]
    J --> L{データあり?}
    L -->|Yes| M[請求書詳細表示]
    L -->|No| N[EmptyDataView表示]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-45-01 | 表示条件 | 請求済み数量(qtyInvoiced)が0より大きい場合のみ表示 | 常時 |
| BR-45-02 | 自己注文のみ | ユーザーは自身の注文の請求書のみ閲覧可能 | 常時 |
| BR-45-03 | 複数請求書対応 | 1注文に複数の請求書がある場合はすべて表示 | 常時 |

### 計算ロジック

請求書表示判定（注文詳細画面）：
```dart
if (orderDetailModel?.items?[0].qtyInvoiced != 0) {
  // 請求書ボタンを表示
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 請求書取得 | invoices | SELECT | 注文IDに紐づく請求書を取得 |
| 請求書取得 | invoice_items | SELECT | 請求書に含まれる商品明細を取得 |

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

#### invoices（GraphQL API経由）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | id, items, formattedPrice等 | order_id = 指定されたorderId | 複数レコード可能 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | API通信エラー | ネットワーク接続不可 | エラー表示 |
| - | データなし | 請求書がない | EmptyDataView表示 |

### リトライ仕様

- 自動リトライなし
- 画面再表示で再取得可能

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

本機能はデータ取得のみのため、トランザクション管理は不要。

## パフォーマンス要件

- データロード：2秒以内

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

- 認証トークンを使用したAPI呼び出し
- 注文IDによるアクセス制御（サーバーサイドで所有者確認）

## 備考

- ShippingAndPaymentInfoウィジェットを再利用して配送・支払い情報を表示
- OrderDetailモデルを引数として渡し、関連情報を共有

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | order_invoices_model.dart | `lib/data_model/order_model/order_invoices_model.dart` | InvoicesModel、ViewInvoicesの構造 |

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

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

**主要処理フロー**:
- **27-31行目**: initStateでOrderInvoiceBlocを取得し、OrderInvoiceFetchDataEventを発行
- **48-61行目**: BlocConsumerでstateの変化を監視しUI更新
- **64-122行目**: invoiceDetails()で請求書情報を表示

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | order_invoice_bloc.dart | `lib/screens/order_invoices/bloc/order_invoice_bloc.dart` | OrderInvoiceFetchDataEventのハンドリング |

**主要処理フロー**:
- **23-33行目**: OrderInvoiceFetchDataEvent処理、getInvoicesList呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | order_invoice_repository.dart | `lib/screens/order_invoices/bloc/order_invoice_repository.dart` | getInvoicesListメソッド |

**主要処理フロー**:
- **21-30行目**: getInvoicesListでApiClient.getInvoicesList呼び出し

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

```
InvoiceScreen (Widget)
    │
    ├─ OrderInvoiceBloc
    │      │
    │      └─ OrderInvoiceRepositoryImp
    │             │
    │             └─ ApiClient.getInvoicesList()
    │
    ├─ OrderInvoiceListDataState
    │      │
    │      └─ InvoicesModel
    │
    └─ ShippingAndPaymentInfo (Widget)
```

### データフロー図

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

orderId ───▶ OrderInvoiceFetchDataEvent ───▶ OrderInvoiceBloc
   │                                              │
   │                                              ▼
   │                                    OrderInvoiceRepository
   │                                              │
   │                                              ▼
   │                                      ApiClient (GraphQL)
   │                                              │
   │                                              ▼
   │                                      InvoicesModel
   │                                              │
   │                                              ▼
   └─────────────────────────────── OrderInvoiceListDataState ───▶ UI更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| invoice_details.dart | `lib/screens/order_invoices/view/invoice_details.dart` | ソース | メイン画面ウィジェット |
| order_invoice_bloc.dart | `lib/screens/order_invoices/bloc/order_invoice_bloc.dart` | ソース | 状態管理BLoC |
| order_invoice_event.dart | `lib/screens/order_invoices/bloc/order_invoice_event.dart` | ソース | イベント定義 |
| order_invoice_state.dart | `lib/screens/order_invoices/bloc/order_invoice_state.dart` | ソース | 状態定義 |
| order_invoice_repository.dart | `lib/screens/order_invoices/bloc/order_invoice_repository.dart` | ソース | リポジトリ層 |
| order_invoices_model.dart | `lib/data_model/order_model/order_invoices_model.dart` | ソース | データモデル |
| shipping_payment_info.dart | `lib/screens/order_detail/widgets/shipping_payment_info.dart` | ソース | 配送・支払い情報UI |
