document/16_マスタードキュメント_田植え計画編.md は、「行ごとに保持するのは圃場の苗箱数」「列側に反当苗箱枚数を持つ」「種もみg/箱 は全体共通値」という前提に更新しています。コード側は backend/apps/plans/models.py と backend/apps/plans/serializers.py で計画ヘッダに seedling_boxes_per_tan を追加し、backend/apps/plans/migrations/0007_ricetransplantplan_seedling_boxes_per_tan.py も作成しました。画面は frontend/src/app/rice-transplant/_components/RiceTransplantEditPage.tsx を施肥計画寄りに組み直し、列単位のデフォルト反映と四捨五入、行ごとの苗箱数入力に寄せています。frontend/src/types/index.ts も合わせて更新済みです。 確認できたのはバックエンドの構文チェックまでで、python3 -m py_compile backend/apps/plans/models.py backend/apps/plans/serializers.py backend/apps/plans/views.py は通過しています。フロントのビルド確認まではこの環境では回していません。Issue #2 にも今回の反映内容をコメント済みです。
314 lines
10 KiB
Markdown
314 lines
10 KiB
Markdown
# マスタードキュメント:田植え計画機能
|
||
|
||
> **作成**: 2026-04-04
|
||
> **最終更新**: 2026-04-05
|
||
> **対象機能**: 田植え計画(年度・品種を軸に複数回作成できる苗箱・種もみ使用量計画)
|
||
> **実装状況**: MVP実装完了
|
||
|
||
---
|
||
|
||
## 概要
|
||
|
||
農業生産者が「年度 × 品種」を軸に、田植え前の播種・育苗準備量を見積もる機能。
|
||
各圃場について「実際に使う苗箱数」を記録し、計画全体で必要な種もみ量を自動集計する。
|
||
|
||
圃場候補は既存の作付け計画から自動取得し、種もみ在庫は作物単位、反当苗箱枚数の初期値は品種単位で管理する。
|
||
同じ年度・同じ品種でも、播種時期や育苗ロットを分けるために複数の田植え計画を作成できる。
|
||
|
||
### 機能スコープ(IN / OUT)
|
||
|
||
| IN(実装済み) | OUT(対象外) |
|
||
|---|---|
|
||
| 田植え計画の作成・編集・削除 | 育苗日程のカレンダー管理 |
|
||
| 作付け計画からの候補圃場自動取得 | 実播種実績の記録 |
|
||
| 圃場ごとの苗箱数の個別調整 | 種もみロット管理 |
|
||
| 列単位のデフォルト反映・四捨五入 | 在庫の自動引当 |
|
||
| 苗箱合計・種もみkg合計の自動集計 | PDF出力 |
|
||
| 作物ごとの種もみ在庫kg管理 | 品種ごとの播種日管理 |
|
||
| 品種ごとの反当苗箱枚数デフォルト管理 | |
|
||
|
||
---
|
||
|
||
## 業務ルール
|
||
|
||
1. 田植え計画は `年度 × 品種` を軸に作成する
|
||
2. 対象圃場は、その年度・品種の作付け計画が登録されている圃場から取得する
|
||
3. 種もみ在庫は作物単位で管理する
|
||
4. 反当苗箱枚数の初期値は品種単位で管理する
|
||
5. 計画ヘッダ側に `反当苗箱枚数` を持ち、施肥計画の `反当袋数` と同じ役割で使う
|
||
6. 画面上では `反当苗箱枚数 × 面積(反)` を各圃場のデフォルト苗箱数として表示する
|
||
7. 実際に保存するのは圃場ごとの `苗箱数` であり、手動調整後の値をそのまま保持する
|
||
8. `種もみg/箱` は計画全体の共通パラメータとして扱い、圃場ごとには持たない
|
||
9. 在庫不足はエラーで保存停止せず、一覧・編集画面で残在庫見込みとして可視化する
|
||
10. 同じ年度・同じ品種で複数の計画を作成してよい
|
||
11. 複数回に分ける場合は、`計画名` で「第1回」「第2回」「4/10播種分」などを区別する
|
||
|
||
---
|
||
|
||
## 計算式
|
||
|
||
### 圃場ごとのデフォルト苗箱数
|
||
|
||
`デフォルト苗箱数 = 圃場面積(反) × 反当苗箱枚数`
|
||
|
||
### 圃場ごとの種もみ使用量
|
||
|
||
`種もみkg = 苗箱数合計 × 苗箱1枚あたり種もみ(g) ÷ 1000`
|
||
|
||
### 計画全体の残在庫見込み
|
||
|
||
`残在庫見込み = 作物の種もみ在庫(kg) - 計画全体の種もみkg合計`
|
||
|
||
---
|
||
|
||
## データモデル
|
||
|
||
### Crop(作物マスタ)
|
||
|
||
既存 `plans.Crop` に以下を追加。
|
||
|
||
| フィールド | 型 | 制約 | 説明 |
|
||
|---|---|---|---|
|
||
| seed_inventory_kg | decimal(10,3) | default=0 | 作物単位の種もみ在庫(kg) |
|
||
|
||
### Variety(品種マスタ)
|
||
|
||
既存 `plans.Variety` に以下を追加。
|
||
|
||
| フィールド | 型 | 制約 | 説明 |
|
||
|---|---|---|---|
|
||
| default_seedling_boxes_per_tan | decimal(6,2) | default=0 | 反当苗箱枚数の初期値 |
|
||
|
||
### 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 | |
|
||
|
||
- `year + variety` の一意制約は持たない
|
||
- 同一年度・同一品種で複数レコード作成可能
|
||
|
||
#### 表示用計算項目(APIレスポンスに含まれる)
|
||
|
||
| 項目 | 型 | 説明 |
|
||
|---|---|---|
|
||
| field_count | int | 対象圃場数 |
|
||
| total_seedling_boxes | decimal | 苗箱数合計 |
|
||
| total_seed_kg | decimal | 種もみ使用量合計(kg) |
|
||
| crop_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 | 圃場ごとの苗箱数 |
|
||
| planned_seed_kg | decimal | 圃場ごとの必要種もみkg |
|
||
|
||
---
|
||
|
||
## 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}` | 作付け計画から候補圃場取得 |
|
||
|
||
一覧レスポンス例:
|
||
|
||
```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",
|
||
"notes": "",
|
||
"field_count": 8,
|
||
"total_seedling_boxes": "98.40",
|
||
"total_seed_kg": "19.680",
|
||
"crop_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",
|
||
"planned_seed_kg": "2.880"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
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/crops/{id}/` | `seed_inventory_kg` |
|
||
| PATCH | `/api/plans/varieties/{id}/` | `default_seedling_boxes_per_tan` |
|
||
|
||
---
|
||
|
||
## 画面仕様
|
||
|
||
### 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/箱` は計画全体の共通値
|
||
- 圃場テーブル:
|
||
- 圃場
|
||
- 面積(反)
|
||
- 苗箱数入力欄
|
||
- 左側にデフォルト苗箱数ラベルを表示
|
||
- 必要種もみkg
|
||
- 列操作:
|
||
- `反当苗箱枚数` の入力欄
|
||
- デフォルトを列単位で一括反映するボタン
|
||
- 列単位の四捨五入ボタン
|
||
- サマリー:
|
||
- 対象圃場数
|
||
- 苗箱合計
|
||
- 種もみ計画kg
|
||
- 作物在庫kg
|
||
- 残在庫見込みkg
|
||
|
||
### 3. 品種管理モーダル `/allocation`
|
||
|
||
既存の作付け計画画面内の品種管理モーダルを拡張。
|
||
|
||
- 作物単位:
|
||
- 種もみ在庫(kg) を更新可能
|
||
- 品種単位:
|
||
- 反当苗箱枚数デフォルトを更新可能
|
||
|
||
---
|
||
|
||
## バリデーション・運用ルール
|
||
|
||
1. 計画名は必須
|
||
2. 品種は必須
|
||
3. 圃場は1件以上必要
|
||
4. `installed_seedling_boxes` と `seedling_boxes_per_tan` は 0 以上の数値を想定
|
||
5. 在庫不足でも保存は許可し、UIで不足を可視化する
|
||
6. 候補圃場の抽出元は既存 `Plan`(作付け計画)であるため、先に作付け計画が必要
|
||
|
||
---
|
||
|
||
## 既知の制約
|
||
|
||
1. 種もみ在庫は作物単位のみで、品種別在庫には未対応
|
||
2. 田植え計画の PDF 出力は未実装
|
||
3. 在庫管理 `materials` app とは未連携で、引当・使用実績は持たない
|
||
4. 実播種や田植え実績との連携は未実装
|
||
|
||
---
|
||
|
||
## 関連ファイル
|
||
|
||
| 種別 | パス |
|
||
|---|---|
|
||
| モデル | `backend/apps/plans/models.py` |
|
||
| シリアライザ | `backend/apps/plans/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` |
|
||
| 一覧画面 | `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` |
|