Files
keinasystem/backend/apps/plans/models.py
2026-04-05 16:32:57 +09:00

179 lines
5.8 KiB
Python

from django.db import models
from apps.fields.models import Field
class Crop(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name="作物名")
base_temp = models.FloatField(default=0.0, verbose_name="有効積算温度 基準温度(℃)")
seed_inventory_kg = models.DecimalField(
max_digits=10,
decimal_places=3,
default=0,
verbose_name="種もみ在庫(kg)",
)
class Meta:
verbose_name = "作物マスタ"
verbose_name_plural = "作物マスタ"
def __str__(self):
return self.name
class Variety(models.Model):
crop = models.ForeignKey(Crop, on_delete=models.CASCADE, related_name='varieties', verbose_name="作物")
name = models.CharField(max_length=100, verbose_name="品種名")
default_seedling_boxes_per_tan = models.DecimalField(
max_digits=6,
decimal_places=2,
default=0,
verbose_name="反当苗箱枚数デフォルト",
)
seed_material = models.ForeignKey(
'materials.Material',
on_delete=models.SET_NULL,
related_name='varieties',
verbose_name='種子在庫資材',
blank=True,
null=True,
limit_choices_to={'material_type': 'seed'},
)
class Meta:
verbose_name = "品種マスタ"
verbose_name_plural = "品種マスタ"
unique_together = [['crop', 'name']]
def __str__(self):
return f"{self.crop.name} - {self.name}"
class Plan(models.Model):
field = models.ForeignKey(Field, on_delete=models.CASCADE, related_name='plans', verbose_name="圃場")
year = models.IntegerField(verbose_name="作付年度")
crop = models.ForeignKey(Crop, on_delete=models.CASCADE, related_name='plans', verbose_name="作物")
variety = models.ForeignKey(Variety, on_delete=models.SET_NULL, related_name='plans', verbose_name="品種", blank=True, null=True)
notes = models.TextField(blank=True, null=True, verbose_name="備考")
class Meta:
verbose_name = "作付け計画"
verbose_name_plural = "作付け計画"
unique_together = [['field', 'year']]
ordering = ['-year', 'field']
def __str__(self):
return f"{self.field.name} - {self.year} - {self.crop.name}"
class PlanVarietyChange(models.Model):
field = models.ForeignKey(
Field,
on_delete=models.PROTECT,
related_name='plan_variety_changes',
verbose_name='圃場',
)
year = models.IntegerField(verbose_name='作付年度')
plan = models.ForeignKey(
Plan,
on_delete=models.CASCADE,
related_name='variety_changes',
verbose_name='作付け計画',
)
changed_at = models.DateTimeField(auto_now_add=True, verbose_name='変更日時')
old_variety = models.ForeignKey(
Variety,
on_delete=models.SET_NULL,
related_name='old_plan_variety_changes',
verbose_name='変更前品種',
null=True,
blank=True,
)
new_variety = models.ForeignKey(
Variety,
on_delete=models.SET_NULL,
related_name='new_plan_variety_changes',
verbose_name='変更後品種',
null=True,
blank=True,
)
reason = models.TextField(blank=True, default='', verbose_name='変更理由')
moved_entry_count = models.IntegerField(default=0, verbose_name='移動エントリ数')
class Meta:
verbose_name = '作付け計画品種変更履歴'
verbose_name_plural = '作付け計画品種変更履歴'
ordering = ['-changed_at', '-id']
def __str__(self):
old_name = self.old_variety.name if self.old_variety else '未設定'
new_name = self.new_variety.name if self.new_variety else '未設定'
return f'{self.field.name} {self.year}: {old_name} -> {new_name}'
class RiceTransplantPlan(models.Model):
name = models.CharField(max_length=200, verbose_name='計画名')
year = models.IntegerField(verbose_name='年度')
variety = models.ForeignKey(
Variety,
on_delete=models.PROTECT,
related_name='rice_transplant_plans',
verbose_name='品種',
)
default_seed_grams_per_box = models.DecimalField(
max_digits=8,
decimal_places=2,
default=0,
verbose_name='苗箱1枚あたり種もみ(g)デフォルト',
)
seedling_boxes_per_tan = models.DecimalField(
max_digits=6,
decimal_places=2,
default=0,
verbose_name='反当苗箱枚数',
)
notes = models.TextField(blank=True, default='', verbose_name='備考')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = '田植え計画'
verbose_name_plural = '田植え計画'
ordering = ['-year', 'variety']
def __str__(self):
return f'{self.year} {self.name}'
class RiceTransplantEntry(models.Model):
plan = models.ForeignKey(
RiceTransplantPlan,
on_delete=models.CASCADE,
related_name='entries',
verbose_name='田植え計画',
)
field = models.ForeignKey(
Field,
on_delete=models.CASCADE,
related_name='rice_transplant_entries',
verbose_name='圃場',
)
installed_seedling_boxes = models.DecimalField(
max_digits=8,
decimal_places=2,
verbose_name='設置苗箱枚数',
)
seed_grams_per_box = models.DecimalField(
max_digits=8,
decimal_places=2,
verbose_name='苗箱1枚あたり種もみ(g)',
)
class Meta:
verbose_name = '田植え計画エントリ'
verbose_name_plural = '田植え計画エントリ'
unique_together = [['plan', 'field']]
ordering = ['field__display_order', 'field__id']
def __str__(self):
return f'{self.plan} / {self.field} / {self.installed_seedling_boxes}'