# 画面設計書 260-購買契約作成

## 概要

本ドキュメントは、Aureus ERPの購買モジュールにおける「購買契約作成」画面の設計仕様を定義するものです。

### 本画面の処理概要

本画面は、新規購買契約（Purchase Agreement）を作成するための画面です。包括発注（Blanket Order）または購買テンプレート（Purchase Template）のいずれかのタイプを選択して契約を登録します。

**業務上の目的・背景**：
仕入先との長期的な購買条件を事前に合意し、効率的な調達を実現するための契約を登録します。包括発注では有効期間を設定し、購買テンプレートでは繰り返し使用するパターンを定義します。

**画面へのアクセス方法**：
1. 購買契約一覧画面の「新規作成」ボタンをクリック
2. URL直接アクセス：`/admin/purchases/orders/purchase-agreements/create`

**主要な操作・処理内容**：
1. 基本情報（仕入先、担当者、通貨、契約タイプ等）の入力
2. 有効期間の設定（包括発注の場合）
3. 商品明細の登録
4. 備考・利用規約の入力
5. 購買契約の保存

**画面遷移**：
- 遷移元：購買契約一覧画面
- 遷移先：購買契約編集画面（作成成功後）

**権限による表示制御**：
購買モジュールの作成権限を持つユーザーのみがアクセス可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| FN-PURCH-010 | 購買契約作成 | 主機能 | 購買契約データの新規登録 |
| FN-PURCH-009 | 購買契約一覧 | 遷移元機能 | 一覧画面からの遷移 |
| FN-PURCH-011 | 購買契約編集 | 遷移先機能 | 作成成功後の編集画面遷移 |

## 画面種別

作成（Create）

## URL/ルーティング

`/admin/purchases/orders/purchase-agreements/create`

## 画面構成

1. **進捗ステッパー**
   - ステータス表示（DRAFT → ONGOING → CLOSED）

2. **基本情報セクション**
   - 仕入先選択
   - 購買担当者選択
   - 契約タイプ選択（包括発注/購買テンプレート）
   - 通貨選択
   - 有効開始日・終了日（包括発注の場合のみ）
   - 参照番号
   - 会社選択

3. **タブセクション**
   - 商品タブ：契約対象商品の登録
   - 追加情報タブ：カスタムフィールド（存在する場合）
   - 備考タブ：利用規約・備考

4. **フッターアクション**
   - 保存ボタン
   - キャンセルボタン

## 入出力項目

| No | 項目名 | データ型 | 必須 | 初期値 | バリデーション | 説明 |
|----|--------|----------|------|--------|----------------|------|
| 1 | 仕入先（partner_id） | Integer/Select | ○ | - | 存在確認、sub_type=supplier | 仕入先マスタから選択 |
| 2 | 購買担当者（user_id） | Integer/Select | - | - | - | 担当者選択 |
| 3 | 契約タイプ（type） | Enum/Select | ○ | BLANKET_ORDER | - | 包括発注/購買テンプレート |
| 4 | 通貨（currency_id） | Integer/Select | ○ | - | - | 通貨マスタから選択 |
| 5 | 有効開始日（starts_at） | Date | - | - | date, after_or_equal:today | 契約開始日（包括発注のみ） |
| 6 | 有効終了日（ends_at） | Date | - | - | date, after_or_equal:starts_at | 契約終了日（包括発注のみ） |
| 7 | 参照番号（reference） | String | - | - | 最大255文字 | 外部参照番号 |
| 8 | 会社（company_id） | Integer/Select | ○ | ユーザーデフォルト会社 | - | 会社マスタから選択 |
| 9 | 備考（description） | Text/RichEditor | - | - | - | 利用規約・備考 |

### 商品明細（lines）

| No | 項目名 | データ型 | 必須 | 初期値 | バリデーション | 説明 |
|----|--------|----------|------|--------|----------------|------|
| 1 | 商品（product_id） | Integer/Select | ○ | - | 存在確認、type=GOODS | 商品マスタから選択 |
| 2 | 数量（qty） | Decimal | ○ | 0 | 0以上 | 契約数量 |
| 3 | 単位（uom_id） | Integer/Select | 設定依存 | 商品から自動設定 | - | 単位選択（UOM設定時のみ） |
| 4 | 単価（price_unit） | Decimal | ○ | 0 | 0以上 | 契約単価 |

## 表示項目

| No | 項目名 | データ型 | 説明 | 表示条件 |
|----|--------|----------|------|---------|
| 1 | 状態ステッパー（state） | Badge | 現在のステータスをステップ形式で表示 | 常時 |
| 2 | 有効期間設定項目 | フォーム | 開始日・終了日 | type=BLANKET_ORDERの場合のみ |

## イベント仕様

### 1-契約タイプ選択変更

契約タイプ（type）を変更すると、以下の表示制御が行われます：
- 包括発注（BLANKET_ORDER）：有効開始日・終了日が表示
- 購買テンプレート（PURCHASE_TEMPLATE）：有効期間項目が非表示

### 2-仕入先選択変更

仕入先を選択すると、仕入先のデフォルト通貨が自動設定されます（存在する場合）。

### 3-商品選択変更

商品（product_id）を選択すると、以下の項目が自動設定されます：
- 商品の単位 → uom_id

### 4-有効開始日変更

有効開始日（starts_at）が変更されると、有効終了日（ends_at）がクリアされ、終了日の最小日付が開始日に更新されます。

### 5-保存ボタン押下

フォーム内容を検証し、問題がなければ購買契約を作成します。作成成功後、編集画面に遷移します。

### 6-キャンセルボタン押下

確認なしで一覧画面に戻ります。

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存 | purchases_requisitions | INSERT | 購買契約ヘッダーの作成 |
| 保存 | purchases_requisition_lines | INSERT | 購買契約明細の作成 |

### テーブル別更新項目詳細

#### purchases_requisitions（INSERT）

| 項目（カラム名） | 値・取得元 | 備考 |
|-----------------|-----------|------|
| name | 自動生成（BO/{id}またはPT/{id}） | 作成後に更新 |
| state | DRAFT | 固定値 |
| type | フォーム入力 | BLANKET_ORDERまたはPURCHASE_TEMPLATE |
| partner_id | フォーム入力 | 必須 |
| currency_id | フォーム入力 | 必須 |
| user_id | フォーム入力 | - |
| company_id | フォーム入力 | 必須 |
| creator_id | ログインユーザーID | 自動設定 |
| starts_at | フォーム入力 | 包括発注の場合のみ |
| ends_at | フォーム入力 | 包括発注の場合のみ |
| reference | フォーム入力 | - |
| description | フォーム入力 | - |

#### purchases_requisition_lines（INSERT）

| 項目（カラム名） | 値・取得元 | 備考 |
|-----------------|-----------|------|
| requisition_id | 親レコードID | 自動設定 |
| product_id | フォーム入力 | 必須 |
| qty | フォーム入力 | 必須 |
| uom_id | フォーム入力 | 設定依存 |
| price_unit | フォーム入力 | 必須 |

## メッセージ仕様

| No | 種別 | メッセージID | メッセージ内容 | 表示条件 |
|----|------|-------------|--------------|---------|
| 1 | 成功 | create.notification.title | 作成完了 | 作成成功時 |
| 2 | 成功 | create.notification.body | 購買契約が正常に作成されました | 作成成功時 |
| 3 | エラー | validation.required | {field}は必須です | 必須項目未入力時 |
| 4 | エラー | validation.date | {field}は有効な日付を入力してください | 日付形式不正時 |
| 5 | エラー | validation.after_or_equal | {field}は{date}以降の日付を入力してください | 日付範囲エラー時 |

## 例外処理

| No | 例外条件 | 処理内容 |
|----|---------|---------|
| 1 | 必須項目未入力 | バリデーションエラー表示、該当項目をハイライト |
| 2 | 仕入先が存在しない（削除済み） | 選択不可として表示（Deleted表記） |
| 3 | 商品が存在しない（削除済み） | 選択不可として表示（Deleted表記） |
| 4 | 日付範囲エラー | バリデーションエラー表示 |
| 5 | DB保存エラー | エラー通知を表示、ロールバック |
| 6 | 権限不足 | アクセス拒否、一覧画面にリダイレクト |

## 備考

- 本画面は`CreatePurchaseAgreement`クラスで実装され、Filamentの`CreateRecord`を継承
- フォームスキーマは`PurchaseAgreementResource`で定義
- 契約番号は作成後に自動生成（包括発注：BO/XXX、購買テンプレート：PT/XXX）
- 商品選択は重複不可（distinct）
- 削除済みの仕入先・商品は選択不可として表示
- UOM（単位）関連項目は`ProductSettings`の設定により表示/非表示が制御される
- 作成後は`getRedirectUrl()`により編集画面に自動遷移
- 商品はtype=GOODSのもののみ選択可能（is_configurable=nullのもの）
