変更内容

集計ロジックの明確化(農薬取締法の要件を明示):

集計単位の説明に「農薬取締法上、使用回数は作物単位で管理する義務がある」を明記
グループ内に複数作物が混在する場合の動作を明示 → 同一イベントの農薬が水稲・大豆それぞれの回数に +1 カウントされる
集計の正源は SprayEventResolvedField.crop_name_snapshot(圃場ごと)に統一
不要フィールドの削除:

SprayEvent.crop_snapshot / variety_snapshot を削除(役割が SprayEventResolvedField に統合されたため)
APIレスポンス例からも除去
集計式の精緻化:

「1イベント = 1回」のカウント原則を明示(COUNT(DISTINCT SprayEvent.id))— グループ内に圃場が何筆あっても1散布作業は1回
This commit is contained in:
akira
2026-04-09 15:11:15 +09:00
parent 70fe3824b3
commit 3e2942b479

View File

@@ -170,8 +170,6 @@
| target_group | CharField(50) | blank | 対象が圃場グループの場合group_name |
| target_crop | FK(plans.Crop) | null=True, PROTECT | 対象が作物の場合 |
| target_variety | FK(plans.Variety) | null=True, PROTECT | 対象が品種の場合 |
| crop_snapshot | CharField(100) | blank | 保存時点の集計対象作物名 |
| variety_snapshot | CharField(100) | blank | 保存時点の対象品種名 |
| notes | TextField | blank | 備考 |
| created_at | DateTimeField | auto | |
| updated_at | DateTimeField | auto | |
@@ -185,7 +183,7 @@
| `crop` | target_crop | 特定の作物に対して散布(作付け計画と照合) |
| `variety` | target_variety | 特定の品種に対して散布(作付け計画と照合) |
- 保存時に `crop_snapshot` / `variety_snapshot` を自動設定し、後日の作付け変更やグループ名変更があっても過去実績の集計結果が変わらないようにする
- 保存時に全対象圃場を `SprayEventResolvedField` として確定保存し、後日の作付け変更やグループ名変更があっても過去実績の集計結果が変わらないようにする
### SprayEventResolvedField散布イベント対象圃場スナップショット
@@ -229,37 +227,46 @@
### 集計単位
**年度 × 作物** を基本単位とする。
**年度 × 作物** を基本単位とする(農薬取締法上、使用回数は作物単位で管理する義務がある)
- 集計対象作物は `SprayEvent.crop_snapshot``SprayEventResolvedField.crop_name_snapshot` を正とする
- `target_type=field`/`group`/`crop`/`variety` の違いにかかわらず、保存時に解決済み対象圃場と作物スナップショットを作成する
- 使用回数上限の照合は、内部 `Crop` から `PesticideCropAlias` を介して農水省表記へ変換して行う
- 集計対象作物は `SprayEventResolvedField.crop_name_snapshot` を正とする(圃場ごとに記録)
- `target_type=field`/`group`/`crop`/`variety` の違いにかかわらず、保存時に全対象圃場の `SprayEventResolvedField` を作成し、各圃場の作物スナップショットとして保持する
- **グループ内に複数作物が混在する場合**、同一の散布イベント・散布農薬でも作物ごとに使用回数がカウントされる。例グループ内に「水稲」3筆・「大豆」1筆が含まれる場合、そのイベントの農薬は水稲の回数にも大豆の回数にも +1 される
- 使用回数上限の照合は、`SprayEventResolvedField.crop_name_snapshot``PesticideCropAlias``PesticideProductLimit` / `PesticideIngredientLimit` の順に行う
### 製品使用回数の集計
```
製品使用回数 = COUNT(SprayEventPesticide where pesticide=X)
で year × 作物 でフィルタしたもの
製品使用回数年度Y・作物C・農薬P=
COUNT(DISTINCT SprayEvent.id)
where SprayEvent に SprayEventPesticide(pesticide=P) が紐づく
かつ SprayEvent に SprayEventResolvedField(crop_name_snapshot=C) が紐づく
かつ SprayEvent.year = Y
```
※ 1イベントで複数圃場に散布しても、そのイベントは「1回」とカウントする1イベント=1散布作業
### 有効成分総使用回数の集計
```
有効成分総使用回数 = COUNT(SprayEventPesticide)
where SprayEventPesticide.pesticide に
当該有効成分PesticideIngredient.nameが含まれる
かつ PesticideIngredient.is_active=True
かつ is_non_target=False
で year × 作物 でフィルタしたもの
有効成分総使用回数年度Y・作物C・成分名I=
COUNT(DISTINCT SprayEvent.id)
where SprayEvent に SprayEventPesticide が紐づく
かつ SprayEventPesticide.pesticide の PesticideIngredient に
name=I かつ is_active=True のものが存在する
かつ SprayEventPesticide.pesticide.is_non_target=False
かつ SprayEvent に SprayEventResolvedField(crop_name_snapshot=C) が紐づく
かつ SprayEvent.year = Y
```
### 特別栽培・使用成分数の集計
```
使用成分数 = COUNT(DISTINCT PesticideIngredient.name)
where 当該年度×作物の散布イベントで使用された農薬の有効成分
かつ PesticideIngredient.is_active=True
かつ pesticide.is_non_target=False
使用成分数年度Y・作物C=
COUNT(DISTINCT PesticideIngredient.name)
where 上記条件年度Y・作物Cの散布イベントで使用された農薬に含まれる
かつ PesticideIngredient.is_active=True
かつ SprayEventPesticide.pesticide.is_non_target=False
```
---
@@ -418,8 +425,6 @@
"target_type": "group",
"target_group": "田中エリア",
"target_display": "田中エリア(グループ)",
"crop_snapshot": "水稲",
"variety_snapshot": "",
"resolved_fields": [
{
"field": 5,