# 機能設計書 F029-購買依頼管理

## 概要

本ドキュメントは、購買モジュールにおける購買依頼（Purchase Requisition / Purchase Agreement）管理機能の設計を定義するものです。内部購買申請や購買契約（包括契約・価格テンプレート）の作成・承認フローを管理します。

### 本機能の処理概要

購買依頼（内部申請）および購買契約（仕入先との包括契約）を管理する機能です。購買依頼には「包括発注契約（Blanket Order）」と「価格テンプレート（Purchase Template）」の2種類があり、発注の効率化と価格の標準化を支援します。

**業務上の目的・背景**：企業の購買活動において、繰り返し発生する購買に対して契約を締結することでコスト削減と業務効率化が可能です。包括発注契約により数量割引を確保し、価格テンプレートにより標準価格での発注を実現します。

**機能の利用シーン**：購買担当者が仕入先との年間契約を登録する場面、定期的に発生する資材の購買テンプレートを作成する場面、契約に基づいて発注を作成する場面で使用されます。

**主要な処理内容**：
1. 購買契約の作成（包括発注/価格テンプレート）
2. 購買契約の編集・更新
3. 購買契約の承認（状態遷移: draft→ongoing→closed）
4. 契約に基づく発注書の作成
5. 契約明細（商品・数量・価格）の管理

**関連システム・外部連携**：発注書管理（F025）と連携し、契約から発注書を生成できます。見積依頼管理（F026）でも契約を参照可能です。

**権限による制御**：Filament Shieldによる権限制御が適用されます。契約の状態に応じた編集制限も適用されます。OrderSettings.enable_purchase_agreementsで機能の有効/無効を制御できます。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| SCR-PURCH-004 | PurchaseAgreementResource | 主画面 | 購買契約一覧・作成・編集・表示 |
| SCR-PURCH-001 | QuotationResource | 参照画面 | 見積依頼での契約選択 |
| SCR-PURCH-002 | PurchaseOrderResource | 参照画面 | 発注書での契約選択 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | - | 契約番号 | 自動採番 |
| type | enum | Yes | 契約タイプ | blanket_order/purchase_template |
| state | enum | - | 状態 | draft/ongoing/closed |
| reference | string | No | 参照番号 | 最大255文字 |
| partner_id | integer | No | 仕入先ID | 存在する仕入先ID |
| currency_id | integer | Yes | 通貨ID | 存在する通貨ID |
| user_id | integer | No | 担当者ID | 存在するユーザーID |
| company_id | integer | Yes | 会社ID | 存在する会社ID |
| starts_at | datetime | No | 開始日 | 有効な日時 |
| ends_at | datetime | No | 終了日 | 有効な日時（開始日以降） |
| description | text | No | 備考 | - |

### 明細行入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| product_id | integer | Yes | 商品ID | 存在する商品ID |
| qty | decimal | Yes | 数量 | 正の数値 |
| price_unit | decimal | Yes | 単価 | 0以上 |
| uom_id | integer | No | 単位ID | 存在する単位ID |

### 入力データソース

- 画面入力（Filament管理画面のフォーム）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | integer | 購買契約ID |
| name | string | 契約番号（BO/{id}またはPT/{id}） |
| type | enum | 契約タイプ |
| state | enum | 状態 |
| partner_id | integer | 仕入先ID |
| currency_id | integer | 通貨ID |
| starts_at | datetime | 開始日 |
| ends_at | datetime | 終了日 |
| lines | collection | 契約明細 |

### 出力先

- データベーステーブル（purchases_requisitions, purchases_requisition_lines）
- 画面表示（一覧・詳細・編集画面）

## 処理フロー

### 処理シーケンス

```
1. 購買契約一覧表示
   └─ ListPurchaseAgreementsページで契約一覧を表示
2. 購買契約作成
   └─ CreatePurchaseAgreementページ → タイプ選択 → フォーム入力 → 明細追加 → DB保存
   └─ 状態: draft
3. 購買契約編集
   └─ EditPurchaseAgreementページ → 既存データ読込 → フォーム編集 → DB更新
4. 購買契約承認
   └─ Confirm → 状態: ongoing
5. 購買契約終了
   └─ Close → 状態: closed
6. 発注書作成
   └─ 発注書作成時にrequisition_id指定 → 契約明細を自動展開
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[購買契約一覧表示]
    B --> C{ユーザー操作}
    C -->|作成| D[タイプ選択]
    D -->|包括発注| E[包括発注フォーム]
    D -->|価格テンプレート| F[テンプレートフォーム]
    E --> G[明細入力]
    F --> G
    G --> H[保存 state=draft]
    H --> I{次のアクション}
    I -->|承認| J[state=ongoing]
    I -->|編集| K[フォーム編集]
    K --> H
    J --> L{契約使用}
    L -->|発注作成| M[発注書に明細展開]
    L -->|終了| N[state=closed]
    M --> B
    N --> B
    C -->|表示| O[詳細表示]
    O --> B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-029-01 | 契約番号自動採番 | 包括発注:「BO/{id}」、テンプレート:「PT/{id}」 | 作成時 |
| BR-029-02 | タイプ必須 | 契約タイプの選択は必須 | 作成時 |
| BR-029-03 | 状態遷移 | draft→ongoing→closed | 状態変更時 |
| BR-029-04 | 有効期間チェック | 終了日は開始日以降 | 作成・編集時 |
| BR-029-05 | 機能有効化 | OrderSettings.enable_purchase_agreementsで制御 | 常時 |

### 計算ロジック

該当なし（発注時に明細が展開される）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧表示 | purchases_requisitions | SELECT | 購買契約一覧取得 |
| 作成 | purchases_requisitions | INSERT | 新規購買契約登録 |
| 作成 | purchases_requisition_lines | INSERT | 契約明細登録 |
| 編集 | purchases_requisitions | UPDATE | 購買契約情報更新 |
| 状態変更 | purchases_requisitions | UPDATE | state更新 |
| 削除 | purchases_requisitions | SOFT DELETE | 購買契約削除 |

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

#### purchases_requisitions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | - | 契約一覧 |
| INSERT | name, type, state='draft', ... | フォーム入力値、自動採番 | - |
| UPDATE | state | 'ongoing' | 承認時 |
| UPDATE | state | 'closed' | 終了時 |

#### purchases_requisition_lines

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | * | WHERE requisition_id = ? | 明細取得 |
| INSERT | requisition_id, product_id, qty, price_unit, ... | フォーム入力値 | - |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E029-01 | バリデーションエラー | タイプ未選択 | エラーメッセージ表示 |
| E029-02 | バリデーションエラー | 終了日が開始日より前 | エラーメッセージ表示 |
| E029-03 | 状態遷移エラー | 無効な状態遷移 | エラー通知表示 |

### リトライ仕様

該当なし（同期処理のため）

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

- 購買契約と明細は同一トランザクションで処理
- 状態遷移は個別トランザクション

## パフォーマンス要件

- 一覧表示：2秒以内
- 作成・編集：2秒以内

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

- Filament Shieldによる権限制御
- HasCustomFields/HasChatter/HasLogActivityによる監査機能
- CSRF保護（Filament標準機能）
- ソフトデリートによるデータ保護

## 備考

- RequisitionモデルはHasChatter, HasCustomFields, HasLogActivity対応
- RequisitionType enum: BLANKET_ORDER, PURCHASE_TEMPLATE
- RequisitionState enum: DRAFT, ONGOING, CLOSED
- linesリレーションでRequisitionLineを管理
- 発注書作成時にrequisition_id指定で契約明細を自動展開
- 設定（OrderSettings.enable_purchase_agreements）で機能の有効/無効を制御
