# 機能設計書 19-製造オーダー管理

## 概要

本ドキュメントは、InvenTreeシステムにおける製造オーダー管理機能の設計内容を記述した機能設計書である。組立部品の製造指示の作成・管理・完了処理について詳細を定義する。

### 本機能の処理概要

**業務上の目的・背景**：
製造業において、BOM（部品表）に基づいて部品を組み立てて新しい製品を製造する工程管理は中核業務である。製造オーダーは、製造指示の発行から完了までのライフサイクルを管理し、必要な部品の在庫引当・消費、製造出力の追跡を統合的に行う。

**機能の利用シーン**：
- 製造指示を発行して製造を開始する場面
- 部品在庫を製造オーダーに引き当てる場面
- 製造出力（完成品）を登録する場面
- 製造出力を完了して在庫に登録する場面
- 製造オーダーを完了する場面
- 外部委託製造を管理する場面

**主要な処理内容**：
1. 製造オーダーの作成・編集・削除処理
2. 製造オーダーのステータス遷移管理（PENDING→PRODUCTION→COMPLETE/CANCELLED）
3. 製造出力（ビルド出力）の作成・管理・完了
4. 部品在庫の引当・消費処理
5. 親子製造オーダーの階層管理
6. 外部製造オーダーの管理

**関連システム・外部連携**：
- 部品管理との連携（BOM参照）
- 在庫管理との連携（引当・消費・製造出力）
- 販売注文管理との連携（受注生産）
- 発注管理との連携（外部製造）
- 通知システム
- プラグインシステム（イベントトリガー）

**権限による制御**：
- 製造オーダーの作成・編集は製造担当者権限が必要
- 製造オーダーの完了は承認権限が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | 製造インデックス画面 | 主機能 | 製造オーダーの一覧表示（テーブル/カレンダー/パラメトリック） |
| 18 | 製造オーダー詳細画面 | 主機能 | 製造オーダーの詳細表示・編集・発行・完了処理 |
| 14 | 部品詳細画面 | 遷移先機能 | 製造オーダー一覧の表示・製造詳細への遷移 |
| 16 | 在庫アイテム詳細画面 | 結果表示画面 | 製造出力の詳細表示 |
| 20 | 発注書詳細画面 | 関連画面 | 外部製造オーダーとの連携 |

## 機能種別

CRUD操作 / ステータス管理 / 計算処理 / イベント通知

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| reference | CharField | Yes | 製造オーダー番号（最大64文字、一意） | パターン検証、重複チェック |
| part | ForeignKey | Yes | 製造対象部品 | Part、assembly=True必須 |
| quantity | PositiveIntegerField | Yes | 製造数量 | 1以上 |
| title | CharField | No | 説明（最大100文字） | - |
| parent | ForeignKey | No | 親製造オーダー | Build（自己参照） |
| sales_order | ForeignKey | No | 関連販売注文 | SalesOrder |
| take_from | ForeignKey | No | 部品取得元ロケーション | StockLocation |
| destination | ForeignKey | No | 完成品保管先ロケーション | StockLocation |
| batch | CharField | No | バッチコード（最大100文字） | - |
| target_date | DateField | No | 完了予定日 | start_dateより後 |
| start_date | DateField | No | 開始日 | target_dateより前 |
| external | BooleanField | No | 外部製造フラグ | purchaseable部品のみ |
| priority | PositiveIntegerField | No | 優先度 | 0以上 |
| responsible | ForeignKey | No | 責任者 | Owner |
| project_code | ForeignKey | No | プロジェクトコード | ProjectCode |

### 入力データソース

- 画面入力（製造オーダー作成・編集フォーム）
- APIリクエスト
- 販売注文からの自動生成

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| reference | str | 製造オーダー番号 |
| status | int | ステータスコード |
| status_text | str | ステータス表示テキスト |
| quantity | int | 製造数量 |
| completed | int | 完了数量 |
| remaining | int | 残数量 |
| output_count | int | 製造出力数 |
| incomplete_count | int | 未完了出力数 |
| complete_count | int | 完了出力数 |
| is_overdue | bool | 期限超過フラグ |
| can_complete | bool | 完了可能フラグ |
| active | bool | アクティブフラグ |

### 出力先

- build_buildテーブル
- stock_stockitemテーブル（製造出力）
- 通知システム

## 処理フロー

### 処理シーケンス

```
1. 製造オーダーの作成
   └─ reference自動採番
   └─ 組立部品選択
   └─ BOM検証（設定依存）
   └─ 製造ライン（BuildLine）自動生成

2. 製造オーダーの発行（PENDING→PRODUCTION）
   └─ ステータス変更
   └─ 在庫チェック実行

3. 部品引当
   └─ BuildLineへの在庫引当
   └─ BuildItemの作成

4. 製造出力の作成
   └─ StockItem（is_building=True）の作成
   └─ シリアル番号の付与（任意）
   └─ 追跡可能部品の引当（任意）

5. 製造出力の完了
   └─ 追跡可能部品のインストール
   └─ is_building=Falseに変更
   └─ completed数量の増加

6. 製造オーダーの完了（PRODUCTION→COMPLETE）
   └─ 全出力完了チェック
   └─ 未追跡部品の消費処理
   └─ ステータス変更
```

### フローチャート

```mermaid
flowchart TD
    A[製造オーダー作成] --> B{バリデーションOK?}
    B -->|No| C[エラー表示]
    B -->|Yes| D[PENDING状態で保存]
    D --> E[BuildLine生成]
    E --> F{発行可能?}
    F -->|No| G[部品引当]
    F -->|Yes| H[発行処理]
    G --> F
    H --> I[PRODUCTION状態]
    I --> J[製造出力作成]
    J --> K{出力完了?}
    K -->|No| L[部品インストール]
    L --> M[出力完了処理]
    M --> N{全出力完了?}
    N -->|No| J
    N -->|Yes| O{完了可能?}
    O -->|Yes| P[完了処理]
    P --> Q[COMPLETE状態]

    I --> R[キャンセル]
    R --> S[CANCELLED状態]
    D --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | 参照番号一意性 | 製造オーダー番号（reference）はシステム全体で一意 | 製造オーダー作成・編集時 |
| BR-19-02 | 組立部品制約 | assembly=Trueの部品のみ製造対象 | 部品選択時 |
| BR-19-03 | BOM検証 | BUILDORDER_REQUIRE_VALID_BOM設定時、有効なBOM必須 | 製造オーダー作成時 |
| BR-19-04 | アクティブ部品 | BUILDORDER_REQUIRE_ACTIVE_PART設定時、アクティブな部品必須 | 製造オーダー作成時 |
| BR-19-05 | ロック部品 | BUILDORDER_REQUIRE_LOCKED_PART設定時、ロックされた部品必須 | 製造オーダー作成時 |
| BR-19-06 | 完了要件 | 全出力完了、残数量0、未追跡部品完全引当が必要 | 完了処理時 |
| BR-19-07 | 子オーダー制約 | BUILDORDER_REQUIRE_CLOSED_CHILDS設定時、子オーダー完了必須 | 完了処理時 |
| BR-19-08 | 外部製造制約 | 外部製造はpurchaseable=Trueの部品のみ | external=True設定時 |
| BR-19-09 | 責任者必須 | BUILDORDER_REQUIRE_RESPONSIBLE設定時、責任者必須 | 製造オーダー作成時 |

### 計算ロジック

**残数量（remaining）**:
```python
@property
def remaining(self):
    return max(0, self.quantity - self.completed)
```

**完了可能判定（can_complete）**:
```python
@property
def can_complete(self) -> bool:
    if get_global_setting('BUILDORDER_REQUIRE_CLOSED_CHILDS') and self.has_open_child_builds:
        return False
    if self.status != BuildStatus.PRODUCTION.value:
        return False
    if self.incomplete_count > 0:
        return False
    if self.remaining > 0:
        return False
    return self.is_fully_allocated(tracked=False)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 製造オーダー作成 | build_build | INSERT | 新規製造オーダーレコードの作成 |
| 製造ライン生成 | build_buildline | INSERT | BOMに基づくBuildLine自動生成 |
| 製造オーダー発行 | build_build | UPDATE | status→PRODUCTION |
| 製造出力作成 | stock_stockitem | INSERT | is_building=TrueのStockItem作成 |
| 製造出力完了 | stock_stockitem | UPDATE | is_building=False |
| 製造オーダー完了 | build_build | UPDATE | status→COMPLETE |
| 部品消費 | stock_stockitem | UPDATE | 数量削減または削除 |

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

#### build_build

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | reference | 製造オーダー番号 | UNIQUE制約 |
| INSERT/UPDATE | part_id | 部品ID | FK: part_part、assembly=True |
| INSERT/UPDATE | quantity | 製造数量 | PositiveIntegerField |
| UPDATE | status | ステータスコード | 10:PENDING, 20:PRODUCTION, 25:ON_HOLD, 30:COMPLETE, 40:CANCELLED |
| UPDATE | completed | 完了数量 | PositiveIntegerField |
| UPDATE | completion_date | 完了日 | 完了処理時に設定 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| reference_duplicate | ValidationError | 製造オーダー番号が重複 | 別の番号を指定 |
| part_not_assembly | ValidationError | assembly=Falseの部品を指定 | 組立部品を選択 |
| bom_invalid | ValidationError | BOMが検証されていない | BOMを検証 |
| part_not_active | ValidationError | 部品が非アクティブ | 部品をアクティブ化 |
| part_not_locked | ValidationError | 部品がロックされていない | 部品をロック |
| incomplete_outputs | ValidationError | 未完了出力がある状態で完了試行 | 出力を完了 |
| open_child_builds | ValidationError | 子オーダーが未完了 | 子オーダーを完了 |

### リトライ仕様

- データベース一時エラー：トランザクション単位でリトライ
- 部品消費処理：バックグラウンドタスクで実行

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

- 製造オーダーの作成・編集はトランザクション内で実行
- ステータス遷移処理はトランザクション内で完結
- 製造出力の作成・完了は@transaction.atomicで保護
- 部品消費処理はバックグラウンドタスクにオフロード

## パフォーマンス要件

- 製造オーダー一覧表示：1秒以内（100件まで）
- 製造オーダー詳細表示：500ms以内
- 製造出力作成：シリアル化100件で2秒以内
- 部品消費処理：バックグラウンドで非同期実行

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

- 製造オーダーの変更は監査ログに記録
- ステータス遷移はイベントトリガーで追跡
- 製造出力はis_building=Trueで在庫から除外
- 完了者・発行者情報が記録

## 備考

- 製造オーダー番号のパターンはBUILDORDER_REFERENCE_PATTERN設定でカスタマイズ可能
- MPTTによる階層構造で親子製造オーダーを管理
- 追跡可能部品と非追跡可能部品で引当・消費処理が異なる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.py | `src/backend/InvenTree/build/models.py` | Buildクラスの定義 |
| 1-2 | status_codes.py | `src/backend/InvenTree/build/status_codes.py` | BuildStatusの定義 |

**読解のコツ**:
- **76-426行目**: Buildクラスの定義（複数のMixinを継承）
- **242-250行目**: referenceフィールドの定義
- **269-276行目**: partフィールドの定義（assembly制約）
- **316-321行目**: quantityフィールドの定義
- **329-336行目**: statusフィールドの定義

#### Step 2: ステータス遷移を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | models.py | `src/backend/InvenTree/build/models.py` | issue_build(), complete_build()メソッド |
| 2-2 | models.py | `src/backend/InvenTree/build/models.py` | _action_issue(), _action_complete()メソッド |

**主要処理フロー**:
1. **745-754行目**: issue_build()でhandle_transitionを呼び出し
2. **761-774行目**: _action_issue()でステータス変更とチェック処理
3. **647-662行目**: complete_build()でhandle_transitionを呼び出し
4. **664-743行目**: _action_complete()で完了処理

#### Step 3: 製造出力を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | models.py | `src/backend/InvenTree/build/models.py` | create_build_output()メソッド |
| 3-2 | models.py | `src/backend/InvenTree/build/models.py` | complete_build_output()メソッド |

**主要処理フロー**:
- **876-1032行目**: create_build_output()で製造出力を作成
- **1182-1199行目**: complete_build_output()で出力完了

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

```
Build.issue_build()
    │
    └─ handle_transition()
           └─ _action_issue()
                  ├─ status = PRODUCTION
                  ├─ trigger_event(ISSUED)
                  └─ offload_task(check_build_stock)

Build.complete_build()
    │
    └─ handle_transition()
           └─ _action_complete()
                  ├─ 子オーダーチェック
                  ├─ 未完了出力チェック
                  ├─ trim_allocated_stock()
                  ├─ status = COMPLETE
                  ├─ offload_task(complete_build_allocations)
                  ├─ trigger_event(COMPLETED)
                  └─ trigger_notification()

Build.create_build_output()
    │
    ├─ シリアル化判定
    │      ├─ _create_serial_numbers()
    │      └─ 自動引当処理
    │
    └─ 非シリアル化
           └─ StockItem.objects.create()
```

### データフロー図

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

製造オーダー情報 ───▶ バリデーション          ───▶ build_build
  (フォーム)            │                           テーブル
                        │
                        ▼
                  BuildLine生成            ───▶ build_buildline
                        │                           テーブル
                        │
                        ▼
発行コマンド     ───▶ ステータス遷移          ───▶ status = PRODUCTION
                        │
                        ▼
在庫アイテム     ───▶ 部品引当               ───▶ build_builditem
  (選択)                │                           テーブル
                        │
                        ▼
出力作成         ───▶ 製造出力作成           ───▶ stock_stockitem
  (数量/シリアル)       │                           (is_building=True)
                        │
                        ▼
出力完了         ───▶ 出力完了処理           ───▶ stock_stockitem
                        │                           (is_building=False)
                        │
                        ▼
                  製造オーダー完了         ───▶ status = COMPLETE
                        │
                        ▼
                  部品消費処理             ───▶ stock_stockitem
                        │                           (数量削減)
                        ▼
                  通知処理                 ───▶ 通知システム
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| models.py | `src/backend/InvenTree/build/models.py` | ソース | Build、BuildLine、BuildItemモデル定義 |
| status_codes.py | `src/backend/InvenTree/build/status_codes.py` | ソース | BuildStatusの定義 |
| api.py | `src/backend/InvenTree/build/api.py` | ソース | 製造オーダーAPIエンドポイント |
| serializers.py | `src/backend/InvenTree/build/serializers.py` | ソース | 製造オーダーシリアライザー |
| validators.py | `src/backend/InvenTree/build/validators.py` | ソース | 参照番号のバリデーション・生成 |
| events.py | `src/backend/InvenTree/build/events.py` | ソース | BuildEventsの定義 |
| tasks.py | `src/backend/InvenTree/build/tasks.py` | ソース | バックグラウンドタスク |
| filters.py | `src/backend/InvenTree/build/filters.py` | ソース | 引当数量アノテーション |
