田植え計画機能を追加する #1

Closed
opened 2026-04-04 07:50:09 +00:00 by ai · 3 comments
Collaborator

概要

田植え前の播種・育苗準備量を見積もるための「田植え計画」機能を追加する。

施肥計画と同様に年度単位で管理するが、同じ年度・同じ品種でも複数回に分けて苗を作れる前提とする。
計画では圃場ごとに以下を管理する。

  • 反当何枚の苗箱を使うか
  • 苗箱1枚あたり種もみを何g使うか

背景

  • 種もみ在庫は作物単位で管理したい
  • 反当苗箱枚数の初期値は品種単位で持ちたい
  • 実際の計画値は圃場単位で微調整したい
  • 同じ年度・同じ品種でも、第1回・第2回など複数ロットに分けて苗を作ることがある

要件

データモデル

  • Crop に種もみ在庫(kg)を持てること
  • Variety に反当苗箱枚数デフォルトを持てること
  • RiceTransplantPlan を追加し、年度・品種・計画名・苗箱1枚あたり種もみ(g)デフォルト・備考を持てること
  • RiceTransplantEntry を追加し、圃場ごとの反当苗箱枚数と種もみg/箱を持てること
  • 同一年度・同一品種で複数の RiceTransplantPlan を作成できること

業務ロジック

  • 対象圃場は作付け計画から、指定年度・指定品種の圃場を候補として取得すること
  • 苗箱合計 = 面積(反) × 反当苗箱枚数 で計算できること
  • 種もみkg = 苗箱合計 × 種もみg/箱 ÷ 1000 で計算できること
  • 作物在庫との差分から残在庫見込みを表示できること
  • 在庫不足でも保存自体は可能で、画面で不足が分かること

画面

  • 田植え計画一覧画面を追加すること
  • 田植え計画の新規作成・編集・削除ができること
  • 同一年度・同一品種の複数計画を計画名で区別できること
  • 作付け計画画面の品種管理モーダル等から、作物在庫と品種デフォルトを更新できること

受け入れ条件

  • /api/plans/rice-transplant-plans/ で CRUD ができる
  • /api/plans/rice-transplant-plans/candidate_fields/ で候補圃場が取得できる
  • 同じ年度・同じ品種で複数の田植え計画を保存できる
  • 圃場ごとの苗箱合計・種もみkgが自動計算される
  • 計画全体の種もみ合計kgと残在庫見込みkgが確認できる
  • 作物ごとの種もみ在庫kgを更新できる
  • 品種ごとの反当苗箱枚数デフォルトを更新できる
  • 一覧画面から編集・削除ができる

補足

仕様の詳細は document/16_マスタードキュメント_田植え計画編.md を参照。

## 概要 田植え前の播種・育苗準備量を見積もるための「田植え計画」機能を追加する。 施肥計画と同様に年度単位で管理するが、同じ年度・同じ品種でも複数回に分けて苗を作れる前提とする。 計画では圃場ごとに以下を管理する。 - 反当何枚の苗箱を使うか - 苗箱1枚あたり種もみを何g使うか ## 背景 - 種もみ在庫は作物単位で管理したい - 反当苗箱枚数の初期値は品種単位で持ちたい - 実際の計画値は圃場単位で微調整したい - 同じ年度・同じ品種でも、第1回・第2回など複数ロットに分けて苗を作ることがある ## 要件 ### データモデル - `Crop` に種もみ在庫(kg)を持てること - `Variety` に反当苗箱枚数デフォルトを持てること - `RiceTransplantPlan` を追加し、年度・品種・計画名・苗箱1枚あたり種もみ(g)デフォルト・備考を持てること - `RiceTransplantEntry` を追加し、圃場ごとの反当苗箱枚数と種もみg/箱を持てること - 同一年度・同一品種で複数の `RiceTransplantPlan` を作成できること ### 業務ロジック - 対象圃場は作付け計画から、指定年度・指定品種の圃場を候補として取得すること - 苗箱合計 = 面積(反) × 反当苗箱枚数 で計算できること - 種もみkg = 苗箱合計 × 種もみg/箱 ÷ 1000 で計算できること - 作物在庫との差分から残在庫見込みを表示できること - 在庫不足でも保存自体は可能で、画面で不足が分かること ### 画面 - 田植え計画一覧画面を追加すること - 田植え計画の新規作成・編集・削除ができること - 同一年度・同一品種の複数計画を計画名で区別できること - 作付け計画画面の品種管理モーダル等から、作物在庫と品種デフォルトを更新できること ## 受け入れ条件 - [ ] `/api/plans/rice-transplant-plans/` で CRUD ができる - [ ] `/api/plans/rice-transplant-plans/candidate_fields/` で候補圃場が取得できる - [ ] 同じ年度・同じ品種で複数の田植え計画を保存できる - [ ] 圃場ごとの苗箱合計・種もみkgが自動計算される - [ ] 計画全体の種もみ合計kgと残在庫見込みkgが確認できる - [ ] 作物ごとの種もみ在庫kgを更新できる - [ ] 品種ごとの反当苗箱枚数デフォルトを更新できる - [ ] 一覧画面から編集・削除ができる ## 補足 仕様の詳細は `document/16_マスタードキュメント_田植え計画編.md` を参照。
Owner

コードレビュー結果(2026-04-04)

全体評価

設計がシンプルで仕様書と整合しています。単一ユーザーのシステムとして十分な品質です。


指摘事項

1. urls.py — 重複ルート(軽微)

DRF の @actionurl_path = func.__name__ をデフォルト使用するため、router が rice-transplant-plans/candidate_fields/ を自動生成済みです。
urlpatterns に追加している explicit path は冗長(include(router.urls) が先にマッチするため到達されません)。削除してください。

2. serializers.py — entries の重複シリアライズ(軽微)

get_total_seedling_boxesget_total_seed_kgget_remaining_seed_kg がそれぞれ RiceTransplantEntrySerializer(obj.entries.all(), many=True).data を再生成しているため、1プランあたり entries が 3〜4 回シリアライズされます。
39 筆のシングルユーザーでは実害は小さいですが、直接 obj.entries.all() を集計する形に変えるとシンプルになります。

3. serializers.py_save_entries のバリデーション欠如(軽微)

存在しない field_id を渡すと IntegrityError → 500 になります。フロントエンドが正しい値を送ることが前提なので実害はほぼありませんが、validate() で事前チェックを追加しておくと安全です。

4. rice-transplant/page.tsx — 削除確認なし(UX)

削除ボタンが confirm なしで直接 DELETE を発行します。他画面と統一するなら確認ダイアログを追加してください。


問題なし

項目 評価
モデル設計(FK・unique_together) OK
マイグレーション(依存関係) OK
candidate_fields の Plan → field 抽出 OK
型定義 types/index.ts OK
Navbar 追加 OK
計算ロジック(フロント・バック整合) OK
仕様書との一致 OK

優先順位

  1. 対応推奨: 重複ルート削除(urls.py の explicit path 1件削除)
  2. 任意: serializer の重複計算リファクタ
  3. 任意: 削除確認ダイアログ追加
## コードレビュー結果(2026-04-04) ### 全体評価 設計がシンプルで仕様書と整合しています。単一ユーザーのシステムとして十分な品質です。 --- ### 指摘事項 #### 1. `urls.py` — 重複ルート(軽微) DRF の `@action` は `url_path = func.__name__` をデフォルト使用するため、router が `rice-transplant-plans/candidate_fields/` を自動生成済みです。 `urlpatterns` に追加している explicit path は冗長(`include(router.urls)` が先にマッチするため到達されません)。削除してください。 #### 2. `serializers.py` — entries の重複シリアライズ(軽微) `get_total_seedling_boxes`・`get_total_seed_kg`・`get_remaining_seed_kg` がそれぞれ `RiceTransplantEntrySerializer(obj.entries.all(), many=True).data` を再生成しているため、1プランあたり entries が 3〜4 回シリアライズされます。 39 筆のシングルユーザーでは実害は小さいですが、直接 `obj.entries.all()` を集計する形に変えるとシンプルになります。 #### 3. `serializers.py` — `_save_entries` のバリデーション欠如(軽微) 存在しない `field_id` を渡すと `IntegrityError` → 500 になります。フロントエンドが正しい値を送ることが前提なので実害はほぼありませんが、`validate()` で事前チェックを追加しておくと安全です。 #### 4. `rice-transplant/page.tsx` — 削除確認なし(UX) 削除ボタンが confirm なしで直接 DELETE を発行します。他画面と統一するなら確認ダイアログを追加してください。 --- ### 問題なし | 項目 | 評価 | |---|---| | モデル設計(FK・unique_together) | OK | | マイグレーション(依存関係) | OK | | `candidate_fields` の Plan → field 抽出 | OK | | 型定義 `types/index.ts` | OK | | Navbar 追加 | OK | | 計算ロジック(フロント・バック整合) | OK | | 仕様書との一致 | OK | --- ### 優先順位 1. **対応推奨**: 重複ルート削除(urls.py の explicit path 1件削除) 2. **任意**: serializer の重複計算リファクタ 3. **任意**: 削除確認ダイアログ追加
Author
Collaborator

コードレビュー指摘のうち以下を反映しました。

  • backend/apps/plans/urls.py
    • rice-transplant-plans/candidate_fields/ の重複 explicit path を削除しました
  • backend/apps/plans/serializers.py
    • total_seedling_boxes / total_seed_kg を entries の再シリアライズなしで直接集計するように変更しました
    • RiceTransplantPlanWriteSerializer.validate() を追加し、不正な field_id を 400 で弾くようにしました
  • frontend/src/app/rice-transplant/page.tsx
    • 削除前の確認ダイアログを追加しました

確認:

  • python3 -m py_compile backend/apps/plans/serializers.py backend/apps/plans/urls.py は通過しています

残件としては、より細かい UX 改善や追加テストは未対応です。必要なら続けて詰めます。

コードレビュー指摘のうち以下を反映しました。 - `backend/apps/plans/urls.py` - `rice-transplant-plans/candidate_fields/` の重複 explicit path を削除しました - `backend/apps/plans/serializers.py` - `total_seedling_boxes` / `total_seed_kg` を entries の再シリアライズなしで直接集計するように変更しました - `RiceTransplantPlanWriteSerializer.validate()` を追加し、不正な `field_id` を 400 で弾くようにしました - `frontend/src/app/rice-transplant/page.tsx` - 削除前の確認ダイアログを追加しました 確認: - `python3 -m py_compile backend/apps/plans/serializers.py backend/apps/plans/urls.py` は通過しています 残件としては、より細かい UX 改善や追加テストは未対応です。必要なら続けて詰めます。
Author
Collaborator

2026-04-07 時点で実装済みを確認したためクローズします。

確認内容:

  • RiceTransplantPlan / RiceTransplantEntry と、作物在庫・品種デフォルト項目がモデルに追加済み
  • /api/plans/rice-transplant-plans/ の CRUD と /candidate_fields/ が実装済み
  • 一覧画面・新規作成・編集・削除画面が frontend/src/app/rice-transplant/ 配下に実装済み
  • 種もみ計画量、残在庫見込み、同年度・同品種の複数計画前提がコード上で確認できました

関連確認:

  • backend/apps/plans/models.py
  • backend/apps/plans/views.py
  • backend/apps/plans/serializers.py
  • frontend/src/app/rice-transplant/page.tsx
  • frontend/src/app/rice-transplant/_components/RiceTransplantEditPage.tsx
2026-04-07 時点で実装済みを確認したためクローズします。 確認内容: - `RiceTransplantPlan` / `RiceTransplantEntry` と、作物在庫・品種デフォルト項目がモデルに追加済み - `/api/plans/rice-transplant-plans/` の CRUD と `/candidate_fields/` が実装済み - 一覧画面・新規作成・編集・削除画面が `frontend/src/app/rice-transplant/` 配下に実装済み - 種もみ計画量、残在庫見込み、同年度・同品種の複数計画前提がコード上で確認できました 関連確認: - `backend/apps/plans/models.py` - `backend/apps/plans/views.py` - `backend/apps/plans/serializers.py` - `frontend/src/app/rice-transplant/page.tsx` - `frontend/src/app/rice-transplant/_components/RiceTransplantEditPage.tsx`
ai closed this issue 2026-04-07 00:59:22 +00:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: akira/keinasystem#1