# 画面設計書 261-購買契約編集

## 概要

本ドキュメントは、購買モジュールにおける購買契約編集画面の設計を記載しています。この画面では、既存の購買契約（ブランケットオーダーまたは購買テンプレート）の内容を編集・更新することができます。

### 本画面の処理概要

**業務上の目的・背景**：購買契約は、仕入先との長期的な取引条件を定義するための重要なドキュメントです。ブランケットオーダーは一定期間内の複数回の発注に対する包括的な契約であり、購買テンプレートは繰り返し使用する発注パターンを定義します。この画面により、契約内容の変更（商品、数量、価格、有効期間など）を行い、ビジネス要件の変化に対応することができます。

**画面へのアクセス方法**：購買モジュール > 注文 > 購買契約一覧 > 対象レコードの「編集」アクション、または購買契約詳細画面のサブナビゲーションから「編集」を選択してアクセスします。

**主要な操作・処理内容**：
1. 仕入先、購入担当者、契約タイプ、通貨などの基本情報を編集
2. 有効期間（開始日・終了日）の設定・変更（ブランケットオーダーのみ）
3. 参照番号、会社の設定
4. 商品明細（商品、数量、単位、単価）の追加・編集・削除
5. 契約条件（説明）の編集
6. 契約の確認（DRAFT → CONFIRMED）
7. 契約のクローズ（CONFIRMED → CLOSED）
8. 契約のキャンセル（DRAFT/CONFIRMED → CANCELED）
9. PDF印刷による契約書出力
10. Chatter機能によるコミュニケーション・履歴管理

**画面遷移**：
- 遷移元：購買契約一覧画面、購買契約詳細画面
- 遷移先：購買契約詳細画面（保存後）、購買契約一覧画面（削除後）

**権限による表示制御**：
- ステータスがDRAFTの場合のみ、仕入先、購入担当者、契約タイプ、会社フィールドが編集可能
- CLOSEDステータスの場合、削除アクションは非表示
- CLOSEDまたはCANCELEDステータスの場合、商品明細の編集は不可
- CONFIRMEDステータスの場合、「確認」ボタンが非表示、「クローズ」ボタンが表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| FN-PURCH-021 | 購買契約編集 | 主機能 | 既存購買契約の編集・更新 |
| FN-PURCH-022 | 購買契約表示 | 遷移先機能 | 編集完了後の詳細表示 |
| FN-PURCH-019 | 購買契約一覧 | 遷移先機能 | 削除後の一覧表示 |

## 画面種別

編集

## URL/ルーティング

`/admin/purchases/orders/purchase-agreements/{record}/edit`

## 画面構成

- ヘッダーアクションエリア
  - Chatterボタン
  - 確認ボタン（DRAFTステータス時のみ表示）
  - クローズボタン（CONFIRMEDステータス時のみ表示）
  - キャンセルボタン（CLOSED/CANCELED以外で表示）
  - 印刷ボタン
  - 削除ボタン（CLOSED以外で表示）
- ステータス表示エリア（ProgressStepper）
- 基本情報セクション（2カラムレイアウト）
  - 左カラム：仕入先、購入担当者、契約タイプ、通貨
  - 右カラム：有効期間（開始日・終了日）、参照番号、会社
- タブエリア
  - 商品タブ：商品明細リピーター
  - 追加タブ：カスタムフィールド（設定時のみ表示）
  - 条件タブ：契約条件（リッチエディタ）
- サブナビゲーション（詳細/編集切り替え）

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | 型 | 必須 | 桁数 | 初期値 | 説明 |
|--------|--------|----------|-----|------|------|--------|------|
| ステータス | state | 出力 | Enum | - | - | DRAFT | 契約のステータス表示 |
| 仕入先 | partner_id | 入力 | Select | ○ | - | - | 仕入先選択（supplier タイプのみ） |
| 購入担当者 | user_id | 入力 | Select | - | - | - | 担当ユーザー選択 |
| 契約タイプ | type | 入力 | Select | ○ | - | BLANKET_ORDER | ブランケットオーダー/購買テンプレート |
| 通貨 | currency_id | 入力 | Select | ○ | - | - | 通貨選択 |
| 有効開始日 | starts_at | 入力 | Date | - | - | - | 契約の開始日 |
| 有効終了日 | ends_at | 入力 | Date | - | - | - | 契約の終了日 |
| 参照番号 | reference | 入力 | Text | - | 255 | - | 外部参照番号 |
| 会社 | company_id | 入力 | Select | ○ | - | ログインユーザーのデフォルト会社 | 会社選択 |
| 契約条件 | description | 入力 | RichText | - | - | - | 契約の詳細条件 |

### 商品明細（lines）

| 項目名 | 項目ID | 入力/出力 | 型 | 必須 | 桁数 | 初期値 | 説明 |
|--------|--------|----------|-----|------|------|--------|------|
| 商品 | product_id | 入力 | Select | ○ | - | - | 商品選択（GOODS タイプのみ） |
| 数量 | qty | 入力 | Number | ○ | 11 | 0 | 数量 |
| 単位 | uom_id | 入力 | Select | ○ | - | - | 単位選択（UOM有効時） |
| 単価 | price_unit | 入力 | Number | ○ | 11 | 0 | 商品の単価 |

## 表示項目

該当なし（編集画面のため入出力項目を参照）

## イベント仕様

### 1-確認ボタン押下

- 対象：「確認」ボタン（DRAFTステータス時のみ表示）
- 処理：
  1. レコードのstateをCONFIRMEDに更新
  2. フォームを再読み込みして表示を更新
- 画面遷移：同画面（リロード）

### 2-クローズボタン押下

- 対象：「クローズ」ボタン（CONFIRMEDステータス時のみ表示）
- 処理：
  1. レコードのstateをCLOSEDに更新
  2. フォームを再読み込みして表示を更新
- 画面遷移：同画面（リロード）

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

- 対象：「キャンセル」ボタン（CLOSED/CANCELED以外で表示）
- 処理：
  1. レコードのstateをCANCELEDに更新
  2. フォームを再読み込みして表示を更新
- 画面遷移：同画面（リロード）

### 4-印刷ボタン押下

- 対象：「印刷」ボタン
- 処理：
  1. PDF生成（purchases::filament.admin.clusters.orders.purchase-agreements.print テンプレート使用）
  2. A4縦向きでPDFを生成
  3. ファイル名「Purchase Agreement-{契約名}.pdf」でダウンロード

### 5-削除ボタン押下

- 対象：「削除」ボタン（CLOSEDステータス以外で表示）
- 処理：
  1. 確認ダイアログ表示
  2. 確認後、レコードを論理削除
  3. 成功通知を表示
- 画面遷移：購買契約一覧画面

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

- 対象：フォーム保存
- 処理：
  1. 入力バリデーション実行
  2. レコードを更新
  3. 成功通知「購買契約が更新されました」を表示
- 画面遷移：同画面（リロード）

### 7-契約タイプ変更

- 対象：契約タイプ選択フィールド
- 処理：
  1. BLANKET_ORDER選択時：有効期間フィールドを表示
  2. その他選択時：有効期間フィールドを非表示
- 画面遷移：なし（ライブ更新）

### 8-商品選択変更

- 対象：商品明細の商品選択フィールド
- 処理：
  1. 選択した商品のuom_idを自動設定
- 画面遷移：なし（ライブ更新）

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存ボタン押下 | purchases_requisitions | UPDATE | 購買契約の基本情報を更新 |
| 保存ボタン押下 | purchases_requisition_lines | INSERT/UPDATE/DELETE | 商品明細の追加・更新・削除 |
| 確認ボタン押下 | purchases_requisitions | UPDATE | stateをCONFIRMEDに更新 |
| クローズボタン押下 | purchases_requisitions | UPDATE | stateをCLOSEDに更新 |
| キャンセルボタン押下 | purchases_requisitions | UPDATE | stateをCANCELEDに更新 |
| 削除ボタン押下 | purchases_requisitions | UPDATE | deleted_atを設定（論理削除） |

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

#### purchases_requisitions

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | partner_id | フォーム入力値 | 仕入先ID |
| UPDATE | user_id | フォーム入力値 | 購入担当者ID |
| UPDATE | type | フォーム入力値 | 契約タイプ |
| UPDATE | currency_id | フォーム入力値 | 通貨ID |
| UPDATE | starts_at | フォーム入力値 | 有効開始日 |
| UPDATE | ends_at | フォーム入力値 | 有効終了日 |
| UPDATE | reference | フォーム入力値 | 参照番号 |
| UPDATE | company_id | フォーム入力値 | 会社ID |
| UPDATE | description | フォーム入力値 | 契約条件 |
| UPDATE | state | アクションに応じた値 | ステータス変更 |
| UPDATE | updated_at | 現在日時 | 更新日時 |

#### purchases_requisition_lines

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | product_id | フォーム入力値 | 商品ID |
| INSERT/UPDATE | qty | フォーム入力値 | 数量 |
| INSERT/UPDATE | uom_id | フォーム入力値 | 単位ID |
| INSERT/UPDATE | price_unit | フォーム入力値 | 単価 |
| INSERT/UPDATE | requisition_id | 親レコードのID | 購買契約ID |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|--------------|---------|
| MSG-001 | 成功 | 購買契約が更新されました | 保存成功時 |
| MSG-002 | 成功 | 購買契約が削除されました | 削除成功時 |
| MSG-003 | エラー | 必須項目が入力されていません | バリデーションエラー時 |

## 例外処理

| 例外条件 | 処理内容 | 表示メッセージ |
|---------|---------|--------------|
| レコードが存在しない | 404エラー画面を表示 | レコードが見つかりません |
| 権限不足 | 403エラー画面を表示 | アクセス権限がありません |
| CLOSEDステータスで編集不可フィールドを更新 | 更新をブロック | このステータスでは編集できません |
| 削除済み仕入先/会社を選択 | 選択を無効化 | (Deleted)表示で選択不可 |

## 備考

- 購買契約機能は設定（OrderSettings::enable_purchase_agreements）で有効/無効を切り替え可能
- 単位（UOM）フィールドは設定（ProductSettings::enable_uom）で表示/非表示を切り替え可能
- 商品選択は重複不可（distinct）
- 契約名（name）はタイプに応じて自動生成（BO/{id} または PT/{id}）
- Chatter機能により、契約に関するコメントや活動履歴を管理可能
- ソフトデリート対応（論理削除）
- HasCustomFields トレイトによりカスタムフィールドに対応
