Files
keinasystem/document/圃場管理/03_データ仕様書.md
2026-02-21 16:44:36 +09:00

454 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# データ仕様書
> **最終更新**: 2026-02-16
> **変更履歴**: M:N関係に更新、中山間モデル全17列対応、面積単位統一、帳票仕様追加
## 📊 データ構造の全体像
このシステムで扱うデータは3種類
1. **実圃場データ**(吉田農地台帳.ods- 実際に作業する農地
2. **共済マスタ**(水稲共済細目用.ods- 申請書用の区画
3. **中山間マスタ**(中山間.ods- 申請書用の区画
**紐付けの関係:**
- 実圃場 ↔ 共済区画: **M対N**複数の実圃場が1つの共済区画に対応、また1つの実圃場が複数の共済区画に対応するケースもある
- 実圃場 ↔ 中山間区画: **M対N**(同上)
```mermaid
erDiagram
実圃場 }o--o{ 共済区画 : "紐づく(M:N)"
実圃場 }o--o{ 中山間区画 : "紐づく(M:N)"
実圃場 ||--o{ 作付け計画 : "持つ(1:N)"
作付け計画 }o--|| 作物 : "参照"
作付け計画 }o--o| 品種 : "参照(任意)"
作物 ||--o{ 品種 : "持つ"
実圃場 {
int id PK
string 名称
string 住所
decimal 面積_反
int 面積_m2
string 地主
string グループ名
int 表示順
string 細目_耕地番号 "共済紐付けキー(raw)"
string 細目_分筆番号 "共済紐付けキー(raw)"
string 中山間_ID "中山間紐付けキー(raw)"
}
共済区画 {
int id PK
string 地名_地番
int 耕地番号
int 分筆番号
decimal 本地面積_m2
string 漢字地名
}
中山間区画 {
int id PK
string 中山間ID
string 中山間フラグ
string 大字
string 字
string 地番
string 枝番
string 地目
int 農地面積_m2
int 植栽面積_m2
string 作付け品目_元
string 協定管理者
string 所有者
string 傾斜度
int 基本金額
decimal 超急傾斜加算額
decimal スマート農業加算額
int 交付金額
}
作付け計画 {
int id PK
int 実圃場_id FK
int 年度
int 作物_id FK
int 品種_id FK_nullable
text 備考
}
作物 {
int id PK
string 作物名
}
品種 {
int id PK
int 作物_id FK
string 品種名
}
```
---
## 1. 実圃場データ(吉田農地台帳.ods
### ファイル情報
- **行数:** 39行39筆の圃場
- **列数:** 7列
### カラム定義
| カラム名 | データ型 | 必須 | 説明 | 例 |
|---------|---------|-----|------|---|
| 名称 | string | ○ | 圃場の名称(自由記述) | "口神 1反2畝" |
| 住所 | string | ○ | 圃場の住所 | "口神笹ヶ谷374-1)" |
| 面積(反) | float | ○ | 面積(単位: 反※1反=1000m2=10a | 1.20 |
| 地主 | string | ○ | 地主の氏名 | "山崎 出祥" |
| 細目_耕地番号 | int | ○ | 共済マスタとの紐付けキー1/2 | 2 |
| 細目_分筆番号 | int | ○ | 共済マスタとの紐付けキー2/2 | 1 |
| 中山間_ID | int | △ | 中山間マスタとの紐付けキー | 50 |
### DBモデルField
| フィールド名 | データ型 | 説明 |
|-------------|---------|------|
| name | CharField(100) | 圃場名 |
| address | CharField(255) | 住所 |
| area_tan | DecimalField(6,4) | 面積(反) |
| area_m2 | IntegerField | 面積m2= area_tan × 1000 |
| owner_name | CharField(100) | 所有者名 |
| group_name | CharField(50), nullable | グループ名(エリアや用途による分類) |
| display_order | IntegerField, default=0 | リスト表示時の順序 |
| raw_kyosai_k_num | CharField(20), nullable | 細目_耕地番号インポート元の値 |
| raw_kyosai_s_num | CharField(20), nullable | 細目_分筆番号インポート元の値 |
| raw_chusankan_id | CharField(20), nullable | 中山間_IDインポート元の値 |
| kyosai_fields | ManyToManyField → OfficialKyosaiField | 関連共済マスタM:N |
| chusankan_fields | ManyToManyField → OfficialChusankanField | 関連中山間マスタM:N |
| location | PointField, nullable | 位置情報Phase 1では未使用 |
### データサンプル
```
名称 住所 面積(反) 細目_耕地番号 細目_分筆番号 中山間_ID
口神 1反2畝 口神笹ヶ谷374-1) 1.20 2 1 50
口神 北東 口神笹ヶ谷374-1) 0.40 2 2 50
口神 北中 口神笹ヶ谷374-1) 0.43 2 2 50
```
### 特記事項
- **中山間_IDは一部NULL**: 39筆中2筆が中山間の対象外`NaN`
- **同じ共済区画に複数の実圃場**: 例えば共済キー「2-2」には3つの実圃場が紐づく
- **1つの実圃場が複数の申請区画に紐づくケースもある**: M:N関係で対応
- **面積単位**: DB内部では「反DecimalField」と「m2IntegerField」の両方を保持する変換: 1反=1000m2
- **グループ機能**: group_name でエリア分け、display_order で表示順を制御
---
## 2. 共済マスタ(水稲共済細目用.ods
### ファイル情報
- **行数:** 31行31区画
- **列数:** 5列
### カラム定義
| カラム名 | データ型 | 必須 | 説明 | 例 |
|---------|---------|-----|------|---|
| 地名 地番 | string | ○ | 地名と地番(スペース区切り) | "四万十町 ササガタニ 374-1" |
| 耕地番号 | int | ○ | 共済区画の識別子1/2 | 2 |
| 分筆番号 | int | ○ | 共済区画の識別子2/2 | 1 |
| 本地面積 (m2) | float | ○ | 申請上の面積(単位: m2 | 25.4 |
| 漢字地名 | string | ○ | 漢字表記の地名 | "四万十町 笹ヶ谷 374-1" |
### DBモデルOfficialKyosaiField
| フィールド名 | データ型 | 説明 |
|-------------|---------|------|
| k_num | IntegerField | 耕地番号 |
| s_num | IntegerField | 分筆番号 |
| address | CharField(200) | 地名地番 |
| kanji_name | CharField(200) | 漢字地名 |
| area | IntegerField | 本地面積m2 |
**制約:** (k_num, s_num) のペアで一意unique_together
### データサンプル
```
地名 地番 耕地番号 分筆番号 本地面積(m2) 漢字地名
四万十町 ササガタニ 374-1 2 1 25.4 四万十町 笹ヶ谷 374-1
四万十町 ササガタニ 374-1 2 2 12.0 四万十町 笹ヶ谷 374-1
```
### 特記事項
- **面積の不整合は許容**: 役場データが古いため、実圃場の合計面積と一致しないことがある
- 例: 共済キー「2-2」の面積は12.0m2だが、実圃場の合計は1.33反=1330m2
- これは「そういうもの」として扱い、システム側で修正しない
- **重複キーなし**: (耕地番号, 分筆番号)の組み合わせは一意
---
## 3. 中山間マスタ(中山間.ods
### ファイル情報
- **行数:** 71行71区画
- **列数:** 17列全列をDBに保存
### カラム定義全17列
| カラム名 | データ型 | 必須 | 説明 | 例 |
|---------|---------|-----|------|---|
| ID | int | ○ | 中山間区画の識別子 | 1 |
| 中山間 | string | ○ | 中山間フラグ | "" |
| 大字 | string | ○ | 大字名 | "口神ノ川" |
| 字 | string | ○ | 字名 | "壱町切" |
| 地番 | string | ○ | 地番(数値でないケースあり:イ、ロ等) | "1694" |
| 枝番 | string | △ | 枝番(-, 1, イ, ロ等) | "-" |
| 地目 | string | ○ | 地目 | "田" |
| 農地面積 | int | ○ | 農地面積m2 | 2900 |
| 植栽面積 | int | ○ | 植栽面積m2 | 2748 |
| 作付け品目 | string | △ | 役場が記入した作付け品目 | "ニラ" |
| 協定管理者 | string | ○ | 協定管理者名 | "神山倫子" |
| 所有者 | string | △ | 所有者名NULLあり | "谷脇史男" |
| 傾斜度 | string | ○ | 傾斜度 | "1/29" |
| 基本金額 | int | ○ | 基本金額(円) | 23200 |
| 超急傾斜加算額 | decimal | △ | 超急傾斜加算額(円) | 0.0 |
| スマート農業加算額 | decimal | △ | スマート農業加算額(円) | 14500 |
| 交付金額 | int | ○ | 交付金額合計(円) | 37700 |
### DBモデルOfficialChusankanField
| フィールド名 | データ型 | 説明 |
|-------------|---------|------|
| c_id | CharField(20), unique | 中山間ID |
| chusankan_flag | CharField(10), nullable | 中山間フラグ(〇等) |
| oaza | CharField(100) | 大字 |
| aza | CharField(100) | 字 |
| chiban | CharField(50) | 地番(文字列:イ、ロ等があるため) |
| branch_num | CharField(20), nullable | 枝番(-, 1, イ, ロ等) |
| land_type | CharField(20), nullable | 地目(田, 畑等) |
| area | IntegerField | 農地面積m2 |
| planting_area | IntegerField, nullable | 植栽面積m2 |
| original_crop | CharField(100), nullable | 作付け品目(役場記入の元データ) |
| manager | CharField(100), nullable | 協定管理者 |
| owner | CharField(100), nullable | 所有者 |
| slope | CharField(20), nullable | 傾斜度 |
| base_amount | IntegerField, nullable | 基本金額(円) |
| steep_slope_addition | DecimalField, nullable | 超急傾斜加算額(円) |
| smart_agri_addition | DecimalField, nullable | スマート農業加算額(円) |
| payment_amount | IntegerField, nullable | 交付金額(円) |
### データサンプル
```
ID 中山間 大字 字 地番 枝番 地目 農地面積 植栽面積 作付け品目 協定管理者 所有者 傾斜度 基本金額 交付金額
1 口神ノ川 壱町切 1694 - 田 2900 2748 ニラ 神山倫子 1/29 23200 37700
2 口神ノ川 大窪 490 1 田 652 490 野菜 谷脇誠一 谷脇史男 1/20 15204 18824
```
### 特記事項
- **全17列をDBに保存**: 将来どの列が必要になるかわからないため全保存
- **地番・枝番は文字列型**: 「イ」「ロ」などの非数値データが入る
- **作付け品目は参考情報**: 役場が記入した値。システムの作付け計画Planとは別
- **面積の不整合は許容**: 共済マスタと同様、実圃場との差異は受け入れる
---
## 4. 作付け計画データ(システム内部)
### DBモデルPlan
| フィールド名 | データ型 | 必須 | 説明 |
|-------------|---------|-----|------|
| id | int (自動) | ○ | 主キー |
| field | FK → Field | ○ | 実圃場(外部キー) |
| year | IntegerField | ○ | 年度2025など |
| crop | FK → Crop, nullable | △ | 作物(外部キー) |
| variety | FK → Variety, nullable | △ | 品種外部キー、NULLあり |
| notes | TextField, nullable | △ | 備考 |
### 制約
- **ユニーク制約**: (field, year) - 1つの圃場に対して1年度につき1つの作付け計画のみ
- Phase 2で二毛作対応する場合は、この制約を見直す
### 備考
- planting_date播種日、harvest_date収穫日は Phase 2 で追加予定
- crop, variety は外部キー(文字列ではなくリレーション)
---
## 5. 作物マスタ
### DBモデルCrop
| フィールド名 | データ型 | 説明 |
|-------------|---------|------|
| id | int (自動) | 主キー |
| name | CharField(50), unique | 作物名 |
### DBモデルVariety
| フィールド名 | データ型 | 説明 |
|-------------|---------|------|
| id | int (自動) | 主キー |
| crop | FK → Crop | 所属する作物 |
| name | CharField(100) | 品種名 |
**制約:** (crop, name) のペアで一意
### 作物・品種の管理方針
- 初期データは投入しない管理画面またはUIから登録
- すべての作物で品種選択UIは統一
- 「作付けしない」系も特別扱いしない(「その他」作物の品種として扱う)
- 品種の追加・削除は作付け計画画面から可能
---
## 6. データインポート仕様
### 初期セットアップ時
1. **共済マスタのインポート**
- `水稲共済細目用.ods` を読み込み
- `OfficialKyosaiField` テーブルに保存
2. **中山間マスタのインポート**
- `中山間.ods` を読み込み
- `OfficialChusankanField` テーブルに全17列を保存
3. **実圃場データのインポート**
- `吉田農地台帳.ods` を読み込み
- `Field` テーブルに保存
- 同時に共済・中山間マスタとの紐付けを確立ManyToMany:
- `細目_耕地番号` + `細目_分筆番号``OfficialKyosaiField` を検索して M:N 関連に追加
- `中山間_ID``OfficialChusankanField` を検索して M:N 関連に追加
### 紐付けロジック
```python
# 共済マスタとの紐付けM:N
kyosai_record = OfficialKyosaiField.objects.get(
k_num=row['細目_耕地番号'],
s_num=row['細目_分筆番号']
)
field.kyosai_fields.add(kyosai_record)
# 中山間マスタとの紐付けM:N
if pd.notna(row['中山間_ID']):
chusankan_record = OfficialChusankanField.objects.get(
c_id=str(int(row['中山間_ID']))
)
field.chusankan_fields.add(chusankan_record)
```
---
## 7. 申請書PDF出力ロジック
### 水稲共済細目書
**出力形式:**
- A4サイズ、縦向き
- ヘッダー: 「水稲共済細目書YYYY年度
- 表形式罫線あり、1行1区画31行
- フォントサイズ: 10pt
- ページ番号あり
**表の列:**
| 列名 | データ元 | 備考 |
|------|---------|------|
| 漢字地名 | OfficialKyosaiField.kanji_name | 例: 四万十町 笹ヶ谷 374-1 |
| 耕地-分筆 | k_num + "-" + s_num | 例: 2-1 |
| 本地面積 (m2) | OfficialKyosaiField.area | |
| 作付品目 | Plan.crop.name | システムの作付け計画から |
| 品種 | Plan.variety.name | 〃 |
| 圃場名称 | Field.name | 吉田農地台帳の名称 |
**集計ロジック:**
1. 共済マスタ31区画をループ
2. 各共済区画に紐づく実圃場を取得M:N関係
3. 紐づく実圃場の作付け情報を集約(作物名・品種名・圃場名をカンマ区切り)
4. HTMLテンプレートで表を生成 → WeasyPrint で PDF変換
5. 複数の実圃場が紐づく場合 → 作物・品種・圃場名をカンマ区切りで列挙
6. 作付け未設定の場合 → 「未設定」と表示
### 中山間交付金申請
**出力形式:**
- A4サイズ、横向き列が多いため
- ヘッダー: 「中山間地域等直接支払交付金YYYY年度
- 表形式罫線あり、1行1区画71行
- ページ番号あり
**表の列:**
| 列名 | データ元 | 備考 |
|------|---------|------|
| 所在地 | 大字+字+地番+枝番 連結 | 例: 口神ノ川 壱町切 1694 |
| 植栽面積 | OfficialChusankanField.planting_area | m2 |
| 作付け品目(元) | OfficialChusankanField.original_crop | 役場記入の値 |
| 協定管理者 | OfficialChusankanField.manager | |
| 所有者 | OfficialChusankanField.owner | |
| 作物 | Plan.crop.name | システムの作付け計画から |
| 品種 | Plan.variety.name | 〃 |
| 圃場名称 | Field.name | 吉田農地台帳の名称 |
**集計ロジック:**
- 水稲共済と同様、中山間マスタをループして実圃場を集約 → HTMLテンプレート → PDF
---
## 8. データ移行・メンテナンス
### 年度更新
- **圃場マスタ**: 年度をまたいで共通(更新不要)
- **作付け計画**: 年度ごとに独立(前年度コピー機能で複製)
### マスタデータの更新
- **共済・中山間マスタ**: 役場から新しいファイルをもらった場合、再インポート
- 既存データは上書きせず、差分を確認してマージ
- または、全削除→再インポートの2段階処理
### バックアップ
- 全テーブルをCSV/Excelでエクスポート可能にするサーバー移行時にも利用
- 最低5年分のデータを保持補助金監査対応
---
## 9. 面積単位の扱い
システム内部では以下のように統一:
| 用途 | 単位 | DB型 | 変換式 |
|-----|------|------|--------|
| 実圃場の面積DB保存 | 反 + m2 | DecimalField + IntegerField | 1反 = 1000m2 |
| 共済マスタの面積DB保存 | m2 | IntegerField | - |
| 中山間マスタの面積DB保存 | m2 | IntegerField | - |
| 画面表示 | 反 | - | area_m2 / 1000 |
**実装方針:**
- 実圃場: `area_tan`DecimalField`area_m2`IntegerFieldの両方を保持
- 共済・中山間マスタ: `area` は m2IntegerFieldで保存
- 表示時は「反」に統一1反 = 10a = 1000m2
- 入力時は「反」で受け付け、内部で `m2` に変換
---
## 10. データ整合性チェック
### チェック項目
1. **紐付けの存在確認**
- 実圃場の `細目_耕地番号`/`細目_分筆番号` が共済マスタに存在するか
- 実圃場の `中山間_ID` が中山間マスタに存在するか
2. **面積の整合性(参考情報)**
- 1つの共済区画に紐づく実圃場の合計面積と、共済マスタの面積を比較
- ⚠️ 不整合があっても警告のみ(修正はしない)
3. **作付け未設定の検出**
- 指定年度で作付け計画が未設定の圃場をリストアップ
### 実装
- インポート時にバリデーションを実行
- 管理画面で「データ整合性レポート」を表示