# マスタードキュメント：田植え計画機能

> **作成**: 2026-04-04
> **最終更新**: 2026-04-05
> **対象機能**: 田植え計画（年度・種子資材を軸に複数回作成できる苗箱・種もみ使用量計画）
> **実装状況**: MVP実装完了

---

## 概要

農業生産者が「年度 × 種子資材」を軸に、田植え前の播種・育苗準備量を見積もる機能。
各圃場について「実際に使う苗箱数」を記録し、計画全体で必要な種もみ量を自動集計する。

圃場候補は既存の作付け計画から自動取得し、選択した種子資材に紐づく品種を内部的に参照して候補圃場を決める。種もみ在庫は種子資材単位、反当苗箱枚数の初期値は紐づく品種単位で管理する。
同じ年度・同じ種子資材でも、播種時期や育苗ロットを分けるために複数の田植え計画を作成できる。

### 機能スコープ（IN / OUT）

| IN（実装済み） | OUT（対象外） |
|---|---|
| 田植え計画の作成・編集・削除 | 育苗日程のカレンダー管理 |
| 作付け計画からの候補圃場自動取得 | 実播種実績の記録 |
| 圃場ごとの苗箱数の個別調整 | 種もみロット管理 |
| 列単位のデフォルト反映・四捨五入 | 在庫の自動引当 |
| 苗箱合計・種もみkg合計の自動集計 | PDF出力 |
| 種子資材ごとの種もみ在庫参照 | 品種ごとの播種日管理 |
| 品種ごとの反当苗箱枚数デフォルト管理 | |

---

## 業務ルール

1. 田植え計画は `年度 × 種子資材` を軸に作成する
2. 対象圃場は、選択した種子資材に紐づく品種の作付け計画が登録されている圃場から取得する
3. 種もみ在庫は種子資材単位で管理する
4. 反当苗箱枚数の初期値は、種子資材に紐づく品種単位で管理する
5. 計画ヘッダ側に `反当苗箱枚数` を持ち、施肥計画の `反当袋数` と同じ役割で使う
6. 画面上では `反当苗箱枚数 × 面積(反)` を各圃場のデフォルト苗箱数として表示する
7. 実際に保存するのは圃場ごとの `苗箱数` であり、手動調整後の値をそのまま保持する
8. `種もみg/箱` は計画全体の共通パラメータとして扱い、圃場ごとには持たない
9. 在庫不足はエラーで保存停止せず、一覧・編集画面で残在庫見込みとして可視化する
10. 同じ年度・同じ種子資材で複数の計画を作成してよい
11. 複数回に分ける場合は、`計画名` で「第1回」「第2回」「4/10播種分」などを区別する

---

## 計算式

### 圃場ごとのデフォルト苗箱数

`デフォルト苗箱数 = 圃場面積(反) × 反当苗箱枚数`

### 圃場ごとの種もみ使用量

`種もみkg = 苗箱数合計 × 苗箱1枚あたり種もみ(g) ÷ 1000`

### 計画全体の残在庫見込み

`残在庫見込み = 種子資材在庫(kg) - 計画全体の種もみkg合計`

---

## データモデル

### Variety（品種マスタ）

既存 `plans.Variety` に以下を追加・参照する。

| フィールド | 型 | 制約 | 説明 |
|---|---|---|---|
| default_seedling_boxes_per_tan | decimal(6,2) | default=0 | 反当苗箱枚数の初期値 |
| seed_material | FK(materials.Material) 相当 | nullable | その品種に対応する種子在庫 |

### RiceTransplantPlan（田植え計画）

| フィールド | 型 | 制約 | 説明 |
|---|---|---|---|
| id | int | PK | |
| name | varchar(200) | required | 計画名 |
| year | int | required | 年度 |
| variety | FK(plans.Variety) | PROTECT | 内部参照用の品種 |
| seedling_boxes_per_tan | decimal(6,2) | default=0 | 計画で使う反当苗箱枚数 |
| default_seed_grams_per_box | decimal(8,2) | default=0 | 苗箱1枚あたり種もみ(g)の初期値 |
| notes | text | blank | 備考 |
| created_at | datetime | auto | |
| updated_at | datetime | auto | |

- ユーザー操作上の主選択は `種子資材`
- 保存時には、選択した種子資材に紐づく `Variety` を内部的に参照して保持する
- `year + variety` の一意制約は持たない
- 同一年度・同一種子資材で複数レコード作成可能

#### 表示用計算項目（APIレスポンスに含まれる）

| 項目 | 型 | 説明 |
|---|---|---|
| field_count | int | 対象圃場数 |
| total_seedling_boxes | decimal | 苗箱数合計 |
| total_seed_kg | decimal | 種もみ使用量合計(kg) |
| variety_seed_inventory_kg | decimal | 種子資材在庫(kg) |
| remaining_seed_kg | decimal | 残在庫見込み(kg) |

### RiceTransplantEntry（田植え計画エントリ）

| フィールド | 型 | 制約 | 説明 |
|---|---|---|---|
| id | int | PK | |
| plan | FK(RiceTransplantPlan) | CASCADE | |
| field | FK(fields.Field) | CASCADE | |
| installed_seedling_boxes | decimal(8,2) | required | その圃場の苗箱数 |

- `unique_together = ['plan', 'field']`
- 順序: `field__display_order, field__id`

#### 表示用計算項目（entryレスポンスに含まれる）

| 項目 | 型 | 説明 |
|---|---|---|
| field_name | string | 圃場名 |
| field_area_tan | decimal | 圃場面積(反) |
| default_seedling_boxes | decimal | `反当苗箱枚数 × 面積(反)` で求めたデフォルト候補 |
| planned_boxes | decimal | 圃場ごとの苗箱数 |

---

## API エンドポイント

すべて JWT 認証（`Authorization: Bearer <token>`）が必要。

### 田植え計画

| メソッド | URL | 説明 |
|---|---|---|
| GET | `/api/plans/rice-transplant-plans/?year={year}` | 年度別一覧 |
| POST | `/api/plans/rice-transplant-plans/` | 新規作成 |
| GET | `/api/plans/rice-transplant-plans/{id}/` | 詳細取得 |
| PUT/PATCH | `/api/plans/rice-transplant-plans/{id}/` | 更新 |
| DELETE | `/api/plans/rice-transplant-plans/{id}/` | 削除 |
| GET | `/api/plans/rice-transplant-plans/candidate_fields/?year={year}&variety_id={id}` | 内部参照した品種IDで候補圃場取得 |

一覧レスポンス例:

```json
{
  "id": 1,
  "name": "2026年度 にこまる種もみ 田植え計画",
  "year": 2026,
  "variety": 3,
  "variety_name": "にこまる",
  "crop_name": "水稲",
  "seedling_boxes_per_tan": "12.00",
  "default_seed_grams_per_box": "200.00",
  "seed_material_name": "にこまる 種もみ",
  "notes": "",
  "field_count": 8,
  "total_seedling_boxes": "98.40",
  "total_seed_kg": "19.680",
  "variety_seed_inventory_kg": "25.000",
  "remaining_seed_kg": "5.320",
  "entries": [
    {
      "id": 10,
      "field": 5,
      "field_name": "田中上",
      "field_area_tan": "1.2000",
      "installed_seedling_boxes": "14.40",
      "default_seedling_boxes": "14.40",
      "planned_boxes": "14.40"
    }
  ]
}
```

POST/PUT リクエスト例:

```json
{
  "name": "2026年度 にこまる種もみ 田植え計画",
  "year": 2026,
  "variety": 3,
  "seedling_boxes_per_tan": "12.00",
  "default_seed_grams_per_box": "200.00",
  "notes": "",
  "entries": [
    {
      "field_id": 5,
      "installed_seedling_boxes": "14.40"
    },
    {
      "field_id": 6,
      "installed_seedling_boxes": "13.80"
    }
  ]
}
```

更新時は `entries` を全置換する。

### 品種マスタ更新 / 在庫管理

田植え計画に必要な既定値は既存 API で更新する。

| メソッド | URL | 更新項目 |
|---|---|---|
| PATCH | `/api/plans/varieties/{id}/` | `default_seedling_boxes_per_tan` |
| PATCH | `/api/plans/varieties/{id}/` | `seed_material` または同等の種子在庫参照 |
| CRUD | `/api/materials/materials/?material_type=seed` | 種子在庫マスタ |

---

## 画面仕様

### 1. 田植え計画一覧 `/rice-transplant`

- 年度切替
- 田植え計画の一覧表示
- 同一年度・同一種子資材の計画が複数並ぶことを想定する
- 表示列:
  - 計画名
  - 種子資材
  - 圃場数
  - 苗箱合計
  - 種もみ計画kg
  - 残在庫見込みkg
- 行アクション:
  - 編集
  - 削除

### 2. 田植え計画編集 `/rice-transplant/new`, `/rice-transplant/{id}/edit`

- 基本情報:
  - 計画名
    - 同一年度・同一種子資材の複数計画を区別できる名称を付ける
    - 例: `2026年度 にこまる種もみ 第1回`, `2026年度 にこまる種もみ 4/15播種分`
  - 年度
  - 種子資材
  - 苗箱1枚あたり種もみ(g) デフォルト
  - 備考
- 対象圃場:
  - 種子資材選択後に、その資材に紐づく品種の作付け計画から候補圃場を自動取得
  - 新規作成時は候補圃場を初期選択
  - 圃場の追加・除外が可能
- 初期値:
  - `反当苗箱枚数` は紐づく品種マスタの `default_seedling_boxes_per_tan` を初期値として表示
  - `反当苗箱枚数 × 面積(反)` で各圃場のデフォルト苗箱数を求める
  - `種もみg/箱` は計画全体の共通値
- 圃場テーブル:
  - 圃場
  - 面積(反)
    - 小数は 2 桁表示を基本とする
  - 苗箱数入力欄
    - 左側にデフォルト苗箱数ラベルを表示
    - 小数は 1 桁表示を基本とする
- 列操作:
  - `反当苗箱枚数` の入力欄
  - デフォルトを列単位で一括反映するボタン
  - 列単位の四捨五入ボタン
    - 施肥計画の四捨五入ボタンと同じ配置・2ステート動作
- サマリー:
  - 対象圃場数
  - 苗箱合計
  - 種もみ計画kg
  - 種子資材在庫kg
  - 残在庫見込みkg

### 3. 品種管理モーダル `/allocation`

既存の作付け計画画面内の品種管理モーダルを拡張。

- 品種単位:
  - 反当苗箱枚数デフォルトを更新可能

### 4. 資材マスタ `/materials/masters`

- 種子タブ:
  - 種子資材を登録・編集できる
  - 各種子資材に対応する品種を 1 件選んで紐付ける

---

## バリデーション・運用ルール

1. 計画名は必須
2. 種子資材は必須
3. 圃場は1件以上必要
4. `installed_seedling_boxes` と `seedling_boxes_per_tan` は 0 以上の数値を想定
5. 在庫不足でも保存は許可し、UIで不足を可視化する
6. 候補圃場の抽出元は既存 `Plan`（作付け計画）であるため、先に作付け計画が必要

---

## 既知の制約

1. 田植え計画の PDF 出力は未実装
2. 実播種や田植え実績との連携は未実装

---

## 関連ファイル

| 種別 | パス |
|---|---|
| モデル | `backend/apps/plans/models.py` |
| モデル | `backend/apps/materials/models.py` |
| シリアライザ | `backend/apps/plans/serializers.py` |
| シリアライザ | `backend/apps/materials/serializers.py` |
| ViewSet | `backend/apps/plans/views.py` |
| URL | `backend/apps/plans/urls.py` |
| マイグレーション | `backend/apps/plans/migrations/0005_crop_seed_inventory_variety_seedling_boxes_and_rice_transplant.py`, `backend/apps/plans/migrations/0006_rename_seedling_boxes_per_tan_to_installed_seedling_boxes.py`, `backend/apps/plans/migrations/0007_ricetransplantplan_seedling_boxes_per_tan.py`, `backend/apps/plans/migrations/0008_variety_seed_material.py`, `backend/apps/plans/migrations/0009_alter_ricetransplantentry_installed_seedling_boxes.py`, `backend/apps/materials/migrations/0005_material_seed_type.py` |
| 一覧画面 | `frontend/src/app/rice-transplant/page.tsx` |
| 編集画面 | `frontend/src/app/rice-transplant/_components/RiceTransplantEditPage.tsx` |
| ナビゲーション | `frontend/src/components/Navbar.tsx` |
| 品種管理モーダル | `frontend/src/app/allocation/page.tsx` |
| 在庫画面 | `frontend/src/app/materials/page.tsx` |
| 資材マスタ | `frontend/src/app/materials/masters/page.tsx` |
