# 機能設計書 31-仕入先価格管理

## 概要

本ドキュメントは、購買管理モジュールにおける仕入先価格管理機能の設計仕様を定義するものです。仕入先別・商品別の価格情報を一元管理し、購買業務における適正価格での仕入れを支援します。

### 本機能の処理概要

仕入先価格管理機能は、仕入先（ベンダー）ごとに商品の仕入価格を管理するための機能です。数量割引や有効期間付き価格など、柔軟な価格設定を可能にし、購買発注時の価格決定を効率化します。

**業務上の目的・背景**：企業の購買業務において、同一商品でも仕入先によって価格が異なることは一般的です。また、発注数量や契約期間によって価格が変動することもあります。本機能は、これらの複雑な価格情報を一元管理し、発注時に最適な仕入先・価格を選択できるようにすることで、調達コストの最適化を支援します。

**機能の利用シーン**：
- 新規仕入先との取引開始時に価格条件を登録する場面
- 仕入先との価格交渉後に新しい価格を設定する場面
- 数量割引条件を設定する場面
- 発注書作成時に適用される仕入価格を確認する場面

**主要な処理内容**：
1. 仕入先価格情報の登録・編集・削除
2. 商品別・仕入先別の価格一覧表示と検索
3. 数量に応じた価格設定（数量割引）
4. 価格の有効期間設定
5. 割引率の設定
6. リードタイム（納期日数）の管理

**関連システム・外部連携**：購買発注機能と連携し、発注書作成時に登録された仕入先価格を自動適用します。また、商品マスタ、パートナー（仕入先）マスタと連携して動作します。

**権限による制御**：購買管理権限を持つユーザーのみが価格情報の登録・編集・削除を行えます。参照権限を持つユーザーは一覧表示のみ可能です。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| SCR-PURCH-006 | VendorPriceResource | 主画面 | 仕入先価格一覧表示・検索・フィルタ |
| SCR-PURCH-006 | VendorPriceResource/Create | 参照画面 | 新規仕入先価格の作成 |
| SCR-PURCH-006 | VendorPriceResource/Edit | 参照画面 | 既存仕入先価格の編集 |
| SCR-PURCH-006 | VendorPriceResource/View | 参照画面 | 仕入先価格詳細の表示 |
| SCR-PURCH-005 | ProductResource | 参照画面 | 商品別仕入先管理（ManageVendors） |

## 機能種別

CRUD操作 / マスタ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| partner_id | integer | Yes | 仕入先ID | 存在する仕入先であること |
| product_id | integer | No | 商品ID | 存在する商品であること、is_configurable=nullの商品のみ |
| product_name | string | No | 仕入先商品名 | 最大255文字 |
| product_code | string | No | 仕入先商品コード | 最大255文字 |
| delay | integer | No | リードタイム（日数） | 0〜99999999の整数、デフォルト1 |
| min_qty | decimal | No | 最小発注数量 | 0〜99999999999の数値、デフォルト0 |
| price | decimal | No | 単価 | 0〜99999999999の数値、デフォルト0 |
| currency_id | integer | Yes | 通貨ID | 存在する通貨であること |
| starts_at | date | No | 有効期間開始日 | 日付形式 |
| ends_at | date | No | 有効期間終了日 | 日付形式 |
| discount | decimal | No | 割引率（%） | 0〜99999999999の数値、デフォルト0 |
| company_id | integer | No | 会社ID | 存在する会社であること |

### 入力データソース

- 画面入力：仕入先価格登録・編集フォームからのユーザー入力
- DBテーブル：partners（仕入先）、products_products（商品）、supports_currencies（通貨）、supports_companies（会社）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| id | integer | 仕入先価格ID |
| partner.name | string | 仕入先名 |
| product.name | string | 商品名 |
| product_name | string | 仕入先商品名 |
| product_code | string | 仕入先商品コード |
| delay | integer | リードタイム（日数） |
| min_qty | decimal | 最小発注数量 |
| price | decimal | 単価 |
| currency.name | string | 通貨名 |
| starts_at | date | 有効期間開始日 |
| ends_at | date | 有効期間終了日 |
| discount | decimal | 割引率 |
| company.name | string | 会社名 |
| created_at | datetime | 作成日時 |
| updated_at | datetime | 更新日時 |

### 出力先

- 画面表示：仕入先価格一覧画面、詳細画面
- DBテーブル：products_product_suppliers

## 処理フロー

### 処理シーケンス

```
1. 仕入先価格一覧表示
   └─ products_product_suppliersテーブルからデータ取得
   └─ フィルター・ソート条件を適用
   └─ ページネーション処理
   └─ 一覧画面に表示

2. 仕入先価格登録
   └─ 入力フォームでデータ入力
   └─ バリデーション実行
   └─ products_product_suppliersテーブルにINSERT
   └─ 成功通知表示

3. 仕入先価格編集
   └─ 既存データを取得してフォームに表示
   └─ データ編集
   └─ バリデーション実行
   └─ products_product_suppliersテーブルをUPDATE
   └─ 成功通知表示

4. 仕入先価格削除
   └─ 削除確認ダイアログ表示
   └─ products_product_suppliersテーブルからDELETE
   └─ 成功/エラー通知表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{操作種別}
    B -->|一覧表示| C[データ取得]
    C --> D[フィルタ・ソート適用]
    D --> E[一覧表示]

    B -->|登録| F[入力フォーム表示]
    F --> G[データ入力]
    G --> H{バリデーション}
    H -->|OK| I[DBに保存]
    H -->|NG| G
    I --> J[成功通知]

    B -->|編集| K[既存データ取得]
    K --> L[編集フォーム表示]
    L --> M[データ編集]
    M --> N{バリデーション}
    N -->|OK| O[DBを更新]
    N -->|NG| M
    O --> P[成功通知]

    B -->|削除| Q[削除確認]
    Q -->|確認| R{削除実行}
    R -->|成功| S[成功通知]
    R -->|失敗| T[エラー通知]
    Q -->|キャンセル| E

    E --> U[終了]
    J --> U
    P --> U
    S --> U
    T --> U
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-031-001 | 通貨デフォルト | 通貨が未指定の場合、ユーザーのデフォルト会社の通貨を適用 | 新規登録時 |
| BR-031-002 | 会社デフォルト | 会社が未指定の場合、ユーザーのデフォルト会社を適用 | 新規登録時 |
| BR-031-003 | 有効期間チェック | 有効期間内の価格のみが発注時に適用される | 発注書作成時 |
| BR-031-004 | 数量割引適用 | 発注数量がmin_qty以上の場合に価格が適用される | 発注書作成時 |
| BR-031-005 | 並び順管理 | sort列による表示順序の管理 | 一覧表示時 |

### 計算ロジック

**実効価格の算出**：
```
実効価格 = price × (1 - discount / 100)
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 一覧表示 | products_product_suppliers | SELECT | 仕入先価格一覧の取得 |
| 登録 | products_product_suppliers | INSERT | 新規仕入先価格の登録 |
| 編集 | products_product_suppliers | UPDATE | 既存仕入先価格の更新 |
| 削除 | products_product_suppliers | DELETE | 仕入先価格の削除 |

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

#### products_product_suppliers

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | partner_id | フォーム入力値 | 仕入先ID |
| INSERT | product_id | フォーム入力値 | 商品ID（任意） |
| INSERT | product_name | フォーム入力値 | 仕入先商品名 |
| INSERT | product_code | フォーム入力値 | 仕入先商品コード |
| INSERT | delay | フォーム入力値（デフォルト1） | リードタイム |
| INSERT | min_qty | フォーム入力値（デフォルト0） | 最小発注数量 |
| INSERT | price | フォーム入力値（デフォルト0） | 単価 |
| INSERT | currency_id | フォーム入力値 | 通貨ID |
| INSERT | starts_at | フォーム入力値 | 有効期間開始日 |
| INSERT | ends_at | フォーム入力値 | 有効期間終了日 |
| INSERT | discount | フォーム入力値（デフォルト0） | 割引率 |
| INSERT | company_id | フォーム入力値 | 会社ID |
| INSERT | creator_id | 認証ユーザーID | 作成者ID |
| UPDATE | 上記全項目 | フォーム入力値 | 更新対象全項目 |
| DELETE | - | WHERE id = 対象ID | 物理削除 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR-031-001 | バリデーションエラー | 必須項目未入力 | エラーメッセージ表示、入力画面に戻る |
| ERR-031-002 | 外部キー制約エラー | 存在しない仕入先/商品/通貨を指定 | エラーメッセージ表示、正しい値を選択 |
| ERR-031-003 | 削除エラー | 他テーブルから参照されている | エラー通知表示、削除をキャンセル |
| ERR-031-004 | 権限エラー | 操作権限がない | アクセス拒否メッセージ表示 |

### リトライ仕様

通常のCRUD操作のため、リトライ処理は不要です。DBエラー発生時はエラーメッセージを表示し、ユーザーに再操作を促します。

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

- 登録・更新・削除操作は単一レコードへの操作のため、デフォルトのトランザクション管理を使用
- 一括削除時は全レコードの削除を1トランザクションで処理し、エラー発生時は全件ロールバック

## パフォーマンス要件

- 一覧表示：1秒以内にレスポンス
- 登録・更新・削除：2秒以内に完了
- ページネーション：デフォルト表示件数での高速レスポンス

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

- 購買管理権限による操作制限
- SQLインジェクション対策（Eloquent ORMによるパラメータバインディング）
- CSRF対策（Laravelのトークン検証）
- XSS対策（Bladeテンプレートによるエスケープ）

## 備考

- ProductSupplierモデルはWebkul\Product\Models\ProductSupplierを継承
- Spatie\EloquentSortable\Sortableによる並び順管理を実装
- Filament AdminパネルのResource機能を使用
