This commit is contained in:
Akira
2026-02-15 10:56:50 +09:00
parent 60dca6aab1
commit e4da194ebd
7 changed files with 4 additions and 0 deletions

View File

@@ -0,0 +1,437 @@
# データ仕様書
## 📊 データ構造の全体像
このシステムで扱うデータは3種類
1. **実圃場データ**(吉田農地台帳.ods- 実際に作業する農地
2. **共済マスタ**(水稲共済細目用.ods- 申請書用の区画
3. **中山間マスタ**(中山間.ods- 申請書用の区画
**紐付けの関係:**
- 実圃場 → 共済区画: **M対1**複数の実圃場が1つの共済区画に対応
- 実圃場 → 中山間区画: **M対1**複数の実圃場が1つの中山間区画に対応
```mermaid
erDiagram
実圃場 }o--|| 共済区画 : "紐づく(M:1)"
実圃場 }o--|| 中山間区画 : "紐づく(M:1)"
実圃場 ||--o{ 作付け計画 : "持つ(1:N)"
実圃場 {
int id PK
string 名称
string 住所
float 面積_反
string 地主
int 細目_耕地番号 "共済紐付けキー"
int 細目_分筆番号 "共済紐付けキー"
int 中山間_ID "中山間紐付けキー"
}
共済区画 {
int id PK
string 地名_地番
int 耕地番号
int 分筆番号
float 本地面積_m2
string 漢字地名
}
中山間区画 {
int id PK
int ID
string 大字
string 字
int 地番
int 農地面積_m2
int 交付金額
}
作付け計画 {
int id PK
int 実圃場_id FK
int 年度
string 作物
string 品種
date 播種日
date 収穫日
}
```
---
## 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 |
### データサンプル
```
名称 住所 面積(反) 細目_耕地番号 細目_分筆番号 中山間_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つの実圃場が紐づく
- **面積単位**: DB内部では「反」と「m2」の両方を保持する変換: 1反=1000m2
---
## 2. 共済マスタ(水稲共済細目用.ods
### ファイル情報
- **行数:** 31行31区画
- **列数:** 5列
### カラム定義
| カラム名 | データ型 | 必須 | 説明 | 例 |
|---------|---------|-----|------|---|
| 地名 地番 | string | ○ | 地名と地番(スペース区切り) | "四万十町 ササガタニ 374-1" |
| 耕地番号 | int | ○ | 共済区画の識別子1/2 | 2 |
| 分筆番号 | int | ○ | 共済区画の識別子2/2 | 1 |
| 本地面積 (m2) | float | ○ | 申請上の面積(単位: m2 | 25.4 |
| 漢字地名 | string | ○ | 漢字表記の地名 | "四万十町 笹ヶ谷 374-1" |
### データサンプル
```
地名 地番 耕地番号 分筆番号 本地面積(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列うち使用するのは一部
### カラム定義(主要なもの)
| カラム名 | データ型 | 必須 | 説明 | 例 |
|---------|---------|-----|------|---|
| ID | int | ○ | 中山間区画の識別子 | 50 |
| 大字 | string | ○ | 大字名 | "口神ノ川" |
| 字 | string | ○ | 字名 | "壱町切" |
| 地番 | int | ○ | 地番 | 1694 |
| 農地面積 | int | ○ | 面積(単位: m2 | 2900 |
| 作付け品目 | string | △ | (役場が記入、システムでは上書き) | "ニラ" |
| 交付金額 | int | △ | 交付金額 | 37700 |
### データサンプル
```
ID 大字 字 地番 農地面積 作付け品目 交付金額
50 口神ノ川 笹ヶ谷 374 2698 米 xxxxxx
```
### 特記事項
- **使用する列は限定的**: システムでは主に「ID」「大字」「字」「地番」「農地面積」を使用
- **作付け品目は上書き**: 役場が記入した「作付け品目」は参考情報で、システムで上書きする
- **面積の不整合は許容**: 共済マスタと同様、実圃場との差異は受け入れる
---
## 4. 作付け計画データ(システム内部)
### テーブル定義
| カラム名 | データ型 | 必須 | 説明 |
|---------|---------|-----|------|
| id | int | ○ | 主キー(自動採番) |
| field_id | int | ○ | 実圃場ID外部キー |
| year | int | ○ | 年度2025など |
| crop | string | ○ | 作物(「米」「トウモロコシ」など) |
| variety | string | △ | 品種(「にこまる」など) |
| planting_date | date | △ | 播種日/定植日Phase 2 |
| harvest_date | date | △ | 収穫日Phase 2 |
| notes | text | △ | 備考 |
### 制約
- **ユニーク制約**: (field_id, year) - 1つの圃場に対して1年度につき1つの作付け計画のみ
- Phase 2で二毛作対応する場合は、この制約を見直す
---
## 5. 作物マスタ
### 作物リスト
-
- トウモロコシ
- エンドウ
- 野菜
- その他
### 品種の登録方法
**すべての作物で統一されたUI:**
- プリセット品種から選択
- その場で新しい品種を追加可能
- 作物による操作の違いなし
### プリセット品種の例
#### 米
- にこまる
- たちはるか
- たちはるか(特栽)
#### トウモロコシ
- (ユーザーが追加)
#### エンドウ
- 久留米豊
#### 野菜
- (ユーザーが追加)
#### その他
- 完全休耕
- 緑肥(ヘアリーベッチ)
- 緑肥(レンゲ)
- 景観作物(コスモス)
- 景観作物(ヒマワリ)
### 実装上の注意
- すべての作物で `Variety` テーブルに品種を登録
- 「作付けしない」系を特別扱いしない
- UIは完全に統一
---
## 6. データインポート仕様
### 初期セットアップ時
1. **共済マスタのインポート**
- `水稲共済細目用.ods` を読み込み
- `OfficialKyosaiField` テーブルに保存
2. **中山間マスタのインポート**
- `中山間.ods` を読み込み
- `OfficialChusankanField` テーブルに保存
3. **実圃場データのインポート**
- `吉田農地台帳.ods` を読み込み
- `Field` テーブルに保存
- 同時に共済・中山間マスタとの紐付けを確立:
- `細目_耕地番号` + `細目_分筆番号``OfficialKyosaiField.id` を外部キーとして保存
- `中山間_ID``OfficialChusankanField.id` を外部キーとして保存
### 紐付けロジック
```python
# 共済マスタとの紐付け
kyosai_record = OfficialKyosaiField.objects.get(
k_num=row['細目_耕地番号'],
s_num=row['細目_分筆番号']
)
field.kyosai_field_ref = kyosai_record.id
# 中山間マスタとの紐付け
if pd.notna(row['中山間_ID']):
chusankan_record = OfficialChusankanField.objects.get(
c_id=int(row['中山間_ID'])
)
field.chusankan_field_ref = chusankan_record.id
```
---
## 7. 申請書PDF出力ロジック
### 水稲共済細目書
**出力形式:**
- A4サイズ、縦向き
- ヘッダー: 「水稲共済細目書(◯◯年度)」
- 表形式(罫線あり)
- フォントサイズ: 10pt
- ページ番号(複数ページの場合)
**表の列:**
```
耕地番号 | 分筆番号 | 地名地番 | 漢字地名 | 本地面積(m2) | 作付品目 | 品種 | 備考
1 | 1 | 四万十町... | 四万十町... | 2.2 | 米 |にこまる|
2 | 1 | 四万十町... | 四万十町... | 25.4 | 米 |にこまる|
2 | 2 | 四万十町... | 四万十町... | 12.0 |米,野菜|にこまる,トマト|複数圃場
```
**集計ロジック:**
```python
def generate_kyosai_pdf(year):
# 1. データ集約CSVと同じロジック
output_rows = []
for kyosai in OfficialKyosaiField.objects.all().order_by('k_num', 's_num'):
fields = Field.objects.filter(kyosai_field_ref=kyosai.id)
plans = Plan.objects.filter(field__in=fields, year=year)
crops = list(set([p.crop.name for p in plans if p.crop]))
varieties = list(set([p.variety.name for p in plans if p.variety]))
row = {
'耕地番号': kyosai.k_num,
'分筆番号': kyosai.s_num,
'地名地番': kyosai.address,
'漢字地名': kyosai.kanji_name,
'本地面積(m2)': kyosai.area,
'作付品目': ','.join(crops) if crops else '未設定',
'品種': ','.join(varieties) if varieties else '',
'備考': f'{len(fields)}筆合算' if len(fields) > 1 else ''
}
output_rows.append(row)
# 2. HTMLテンプレートで表を生成
html = render_to_string('reports/kyosai_template.html', {
'year': year,
'rows': output_rows
})
# 3. HTML → PDF変換
pdf = HTML(string=html).write_pdf()
return pdf
```
**HTMLテンプレート例reports/kyosai_template.html:**
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
@page { size: A4; margin: 2cm; }
body { font-family: "MS Gothic", monospace; font-size: 10pt; }
h1 { text-align: center; font-size: 14pt; margin-bottom: 20px; }
table { width: 100%; border-collapse: collapse; }
th, td { border: 1px solid black; padding: 5px; text-align: center; }
th { background-color: #f0f0f0; }
</style>
</head>
<body>
<h1>水稲共済細目書({{ year }}年度)</h1>
<table>
<thead>
<tr>
<th>耕地番号</th>
<th>分筆番号</th>
<th>地名地番</th>
<th>漢字地名</th>
<th>本地面積(m2)</th>
<th>作付品目</th>
<th>品種</th>
<th>備考</th>
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td>{{ row.耕地番号 }}</td>
<td>{{ row.分筆番号 }}</td>
<td>{{ row.地名地番 }}</td>
<td>{{ row.漢字地名 }}</td>
<td>{{ row.本地面積(m2) }}</td>
<td>{{ row.作付品目 }}</td>
<td>{{ row.品種 }}</td>
<td>{{ row.備考 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
```
### 中山間交付金申請
**出力形式:**
- A4サイズ、縦向き
- ヘッダー: 「中山間地域等直接支払交付金(◯◯年度)」
- 表形式(罫線あり)
**表の列:**
```
ID | 大字 | 字 | 地番 | 農地面積(m2) | 作付品目 | 品種 | 備考
50 | 口神ノ川 | 笹ヶ谷 | 374 | 2698 | 米,野菜 | にこまる,トマト | 7筆合算
```
**集計ロジック:**
- 水稲共済と同様、中山間マスタをループして実圃場を集約 → HTMLテンプレート → PDF
---
## 8. データ移行・メンテナンス
### 年度更新
- **圃場マスタ**: 年度をまたいで共通(更新不要)
- **作付け計画**: 年度ごとに独立(前年度コピー機能で複製)
### マスタデータの更新
- **共済・中山間マスタ**: 役場から新しいファイルをもらった場合、再インポート
- 既存データは上書きせず、差分を確認してマージ
- または、全削除→再インポートの2段階処理
### バックアップ
- 全テーブルをCSV/Excelでエクスポート可能にする
- 最低5年分のデータを保持補助金監査対応
---
## 9. 面積単位の扱い
システム内部では以下のように統一:
| 表示単位 | DB保存 | 変換式 |
|---------|--------|--------|
| 反(たん) | m2 | 1反 = 1000m2 |
| アールa | m2 | 1a = 100m2 |
| ヘクタールha | m2 | 1ha = 10000m2 |
**実装方針:**
- DB内部は全て `m2` で保存(整数型)
- 表示時にユーザー設定に応じて変換(デフォルトは「反」)
- 入力時は「反」で受け付け、内部で `m2` に変換
---
## 10. データ整合性チェック
### チェック項目
1. **紐付けの存在確認**
- 実圃場の `細目_耕地番号`/`細目_分筆番号` が共済マスタに存在するか
- 実圃場の `中山間_ID` が中山間マスタに存在するか
2. **面積の整合性(参考情報)**
- 1つの共済区画に紐づく実圃場の合計面積と、共済マスタの面積を比較
- ⚠️ 不整合があっても警告のみ(修正はしない)
3. **作付け未設定の検出**
- 指定年度で作付け計画が未設定の圃場をリストアップ
### 実装
- インポート時にバリデーションを実行
- 管理画面で「データ整合性レポート」を表示