# 帳票設計書 9-Stock Report Merge

## 概要

本ドキュメントは、InvenTreeシステムにおける在庫レポート（マージ版）の設計仕様を記載する。このレポートは複数の在庫品目を1つのレポートにマージして出力するPDF形式の帳票である。

### 本帳票の処理概要

本帳票は、複数の在庫品目を選択して1つの統合レポートとして出力する機能を提供する。個別の在庫品目レポートとは異なり、選択した全ての在庫品目の情報を1つのドキュメントにまとめて表示する。

**業務上の目的・背景**：在庫管理において、関連する複数の在庫品目をまとめて確認したい場合がある。例えば、同一ロットの全シリアル品、同一製造オーダーからの全出力品などを一括で出力することで、まとめて管理・配布できる。

**帳票の利用シーン**：複数シリアル品の一括出荷時の添付書類、製造完了時の全出力品リスト、棚卸時の特定条件品目のまとめ出力として利用される。

**主要な出力内容**：
1. 各在庫品目の基本情報（部品名、説明、ロケーション、シリアル/数量）
2. インストール済み品目一覧（該当する場合）

**帳票の出力タイミング**：在庫品目一覧画面で複数選択後、またはAPIから複数品目を指定して出力される。

**帳票の利用者**：倉庫管理者、出荷担当者、品質管理担当者

## 帳票種別

一覧表（統合在庫レポート）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | 在庫品目一覧画面 | /stock/ | 複数選択後レポート出力ボタン |
| - | レポート印刷API | /api/report/print/ | POSTリクエスト（複数items指定） |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | PDF |
| 用紙サイズ | A4（設定により変更可能） |
| 向き | 縦 |
| ファイル名 | output.pdf（テンプレート設定により変更可能） |
| 出力方法 | ダウンロード |
| 文字コード | UTF-8 |

### PDF固有設定

| 項目 | 内容 |
|-----|------|
| パスワード保護 | 無 |
| 印刷制限 | 無 |
| 電子署名 | 無 |

## 帳票レイアウト

### レイアウト概要

複数の在庫品目を連続して表示する。各品目は同一フォーマットで表示される。

```
┌─────────────────────────────────────┐
│  Stock Item Test Report             │
├─────────────────────────────────────┤
│  【Item 1】                         │
│  ┌─────────────────────────────┐   │
│  │ {part_name}          [IMG]  │   │
│  │ {description}               │   │
│  │ {location}                  │   │
│  │ Stock Item ID: {id}         │   │
│  │ Serial: {sn} / Qty: {qty}   │   │
│  └─────────────────────────────┘   │
│  Installed Items (if any)          │
│  ┌─────────────────────────────┐   │
│  │ [img] part  | Serial/Qty    │   │
│  └─────────────────────────────┘   │
│                                     │
│  【Item 2】                         │
│  ┌─────────────────────────────┐   │
│  │ {part_name}          [IMG]  │   │
│  │ ...                         │   │
│  └─────────────────────────────┘   │
│  ...                               │
├─────────────────────────────────────┤
│  {date}         {version}          │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | タイトル | "Stock Item Test Report" | 固定値（top_center） | テキスト |

### 明細部 - 各在庫品目（instancesループ）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 部品名 | 部品のフルネーム | item.part.full_name | テキスト（h2） | - |
| 2 | 説明 | 部品の説明 | item.part.description | テキスト | - |
| 3 | ロケーション | 保管場所 | item.stock_item.location | テキスト（イタリック） | - |
| 4 | Stock Item ID | 在庫品目ID | item.stock_item.pk | テキスト（イタリック） | - |
| 5 | シリアル/数量 | シリアル品はシリアル番号、それ以外は数量 | item.stock_item.serial / item.stock_item.quantity | 条件付き表示 | - |
| 6 | 部品画像 | 部品の画像 | part_image item.part | 画像（4cm） | - |

### 明細部 - インストール済み品目

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 部品画像+名前 | インストール品目の部品 | sub_item.part | 画像+テキスト | 自動 |
| 2 | シリアル/数量 | シリアル品はシリアル、それ以外は数量 | sub_item.serial / sub_item.quantity | 条件付き表示 | 自動 |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | 日付 | 出力日 | date | 日付形式 |
| 2 | バージョン | InvenTreeバージョン | inventree_version | テキスト |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| stock_ids | 対象在庫品目のID配列 | Yes |
| instances | 各品目のコンテキスト配列 | - |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 指定されたID順 | - |

### 改ページ条件

品目数が多い場合、各品目間またはページ下端で改ページ

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

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| stock_stockitem | 在庫品目情報 | 直接参照（複数） |
| part_part | 部品情報 | stockitem.part_id |
| stock_stocklocation | ロケーション | stockitem.location_id |

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

#### stock_stockitem

| 参照項目（カラム名） | 帳票項目との対応 | 取得条件 | 備考 |
|-------------------|----------------|---------|------|
| part | 部品 | - | ForeignKey |
| location | ロケーション | - | ForeignKey |
| serial | シリアル番号 | - | NULL許容 |
| quantity | 数量 | - | - |
| pk | Stock Item ID | - | 主キー |

## 計算仕様

### 計算項目一覧

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

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[出力要求（複数ID）] --> B[パラメータ検証]
    B --> C[各StockItem取得]
    C --> D[各品目のコンテキスト生成]
    D --> E[instancesとして集約]
    E --> F[HTMLレンダリング（forループ）]
    F --> G[WeasyPrintでPDF変換]
    G --> H[DataOutput保存]
    H --> I[ファイル返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | 指定された在庫品目が全て存在しない | No valid items provided to template | 有効な在庫品目IDを指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 最大100在庫品目 |
| 目標出力時間 | 30秒以内 |
| 同時出力数上限 | システム設定による |

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

- 認証済みユーザーのみがレポートを出力可能
- 在庫品目データへのアクセス権限は既存の権限モデルに従う
- 出力ログはDataOutputモデルに記録

## 備考

- テンプレートファイル: `src/backend/InvenTree/report/templates/report/inventree_stock_report_merge.html`
- 基底テンプレート: `inventree_report_base.html`を継承
- ReportTemplate.mergeフラグがTrueの場合に使用される
- instancesループで複数品目を連続表示
- i18n対応済み（多言語対応）

---

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

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

### 推奨読解順序

#### Step 1: マージ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.py | `src/backend/InvenTree/report/models.py` | ReportTemplate.print()（514-565行目）のmerge=True時の処理を確認 |
| 1-2 | models.py | `src/backend/InvenTree/report/models.py` | merge属性（391-395行目）の定義確認 |

**読解のコツ**: merge=Trueの場合、各インスタンスのコンテキストがitem_contextsリストに集約され、instancesキーとしてテンプレートに渡される。

#### Step 2: テンプレートを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inventree_stock_report_merge.html | `src/backend/InvenTree/report/templates/report/` | 帳票全体構造 |

**主要処理フロー**:
- **73行目**: {% for item in instances %}でループ開始
- **74-94行目**: 各在庫品目の情報表示
- **96-121行目**: インストール済み品目セクション
- **122行目**: {% endfor %}でループ終了

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

```
ReportPrint.post() [api.py:253]
    │
    └─ ReportTemplate.print() [report/models.py:465]
           │
           │ (merge=True の場合)
           │
           ├─ base_context() [report/models.py:323]
           │
           ├─ for instance in items:
           │      │
           │      └─ instance.report_context()
           │             │
           │             └─ → item_contexts リストに追加
           │
           ├─ contexts = {**base_context, **report_context, 'instances': item_contexts}
           │
           └─ render() → HTML → PDF
```

### データフロー図

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

Stock IDs[] ──────▶ StockItem.objects.filter() ─────▶ StockItem リスト
                           │
                           ▼
                    for item in items:
                        item.report_context()
                           │
                           ▼
                    item_contexts[] (リスト)
                           │
                           ▼
                    {'instances': item_contexts, ...}
                           │
                           ▼
                    render_to_string() (for item in instances)
                           │
                           ▼
                    HTML → PDF (WeasyPrint) ─────────▶ PDF ファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| inventree_stock_report_merge.html | `src/backend/InvenTree/report/templates/report/` | テンプレート | マージレポートのHTMLテンプレート |
| inventree_report_base.html | `src/backend/InvenTree/report/templates/report/` | テンプレート | レポート共通基底テンプレート |
| models.py | `src/backend/InvenTree/report/` | ソース | ReportTemplateモデル（merge処理含む） |
| models.py | `src/backend/InvenTree/stock/` | ソース | StockItemモデル定義 |
