施肥計画の未散布Entry移動とRESERVE再生成を実装する #6
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
概要
作付け計画の品種変更時に、未散布の施肥Entryのみを新品種側の新規施肥計画へ移動し、RESERVE を再生成する。
決定仕様
{year}年度 {品種名} 施肥計画(品種変更移動)create_reserves_for_plan(plan)により plan 単位で再生成する未散布判定
actual_bags IS NULL→ 未散布で移動対象actual_bags IS NOT NULL and actual_bags < bags→ 一部散布済みで移動不可actual_bags >= bags→ 散布完了で移動不可actual_bags = 0は移動不可側として扱う実装内容
planFK を新品種側新規 plan へ付け替えるPlanVarietyChange.moved_entry_countに移動件数を記録するactual_bags再集計の前提となる invariant を守る受け入れ条件
year + field + fertilizerの Entry が複数 plan にまたがって共存しない関連
実装の評価
move_unspread_entries_for_variety_changeの設計仕様書の決定事項と照合:
仕様 | 実装 | 判定 -- | -- | -- actual_bags IS NULL のみ移動 | .filter(actual_bags__isnull=True) | ✅ actual_bags = 0 は移動不可 | NULL判定のみなので 0 は旧計画に残る | ✅ 移動先は常に新規作成 | FertilizationPlan.objects.create(...) | ✅ RESERVE は plan 単位で再生成 | create_reserves_for_plan(old_plan) / create_reserves_for_plan(new_plan) | ✅ moved_entry_count に件数記録 | plans/services.py で差分があれば save | ✅ calc_settings をコピー | calc_settings=old_plan.calc_settings | ✅(自然な引き継ぎ)process_plan_variety_changeの更新moved_count != change.moved_entry_countの差分チェックは無駄な DB 書き込みを避けるための配慮で適切です。テストの妥当性評価
テスト
test_serializer_update_moves_only_unspread_fertilizer_entriesの検証内容を確認します:テストが検証していること ✅
actual_bags=None)が新計画へ移動するactual_bags=1.0)が旧計画に残るother_field)の未散布エントリが旧計画に残る(他圃場の誤移動がない)calc_settingsが引き継がれるmoved_entry_count = 1が記録される不足している観点(軽微)
①
actual_bags = 0のケース — 仕様書で「0 は移動不可」と明示しているが、そのケースのテストがない。実装がisnull=Trueのみなので 0 は自動的に移動しませんが、テストで担保されていません。②
old_varietyまたはnew_varietyが NULL のケース —move_unspread_entries_for_variety_changeは冒頭でNoneチェックして 0 を返していますが、テストがない。③ 施肥計画が存在しないケース — 作付け品種を変更しても施肥計画がない場合(
moved_count = 0)のテストがない。これら3点は現状の実装が正しく動くケースですが、将来の改修時に壊れても検知できません。今回のスコープとしては許容範囲ですが、必要であれば追加できます。
気になる点(1件・要確認)
同一旧品種計画に同一圃場のエントリが複数肥料分ある場合の new_plan の数
現在の実装では「旧計画1件 → 新計画1件」を作ります。ただし、同じ
old_planの中にactual_bags=Noneのエントリが複数肥料分あっても、新計画は1件しか作りません(同じnew_planにまとめて移動される)。これは正しい動作ですか?コードを追うと:
仕様書(9-2)の記述「
</html>{year}年度 {品種名} 施肥計画(品種変更移動)」という命名から、1つの移動イベントに対して1計画を作る意図と読めるので、これは正しいと思いますが念のため確認させてください。完了
#11 の議論で仕様がB案(全entry移動)に変更され、実装済みです。
確定仕様(B案)
対応コミット
c675b7bMove all fertilization entries on variety change(未散布のみ移動→全entry移動に変更)c90c621Add fertilization plan merge workflow(既存計画へのマージ機能追加)元の受け入れ条件はA案前提で書かれていましたが、B案への変更とマージ機能の追加をもって実装完了とします。