施肥散布実績機能を実装し運搬・作業記録・在庫連携を追加

This commit is contained in:
Akira
2026-03-17 19:28:52 +09:00
parent 865d53ed9a
commit 140d5e5a4d
31 changed files with 2053 additions and 248 deletions

View File

@@ -69,6 +69,13 @@ class FertilizationEntry(models.Model):
Fertilizer, on_delete=models.PROTECT, verbose_name='肥料'
)
bags = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='袋数')
actual_bags = models.DecimalField(
max_digits=10,
decimal_places=4,
null=True,
blank=True,
verbose_name='実績袋数',
)
class Meta:
verbose_name = '施肥エントリ'
@@ -179,3 +186,63 @@ class DeliveryTripItem(models.Model):
def __str__(self):
return f"{self.trip} / {self.field.name} / {self.fertilizer.name}: {self.bags}"
class SpreadingSession(models.Model):
"""散布日単位の実績"""
year = models.IntegerField(verbose_name='年度')
date = models.DateField(verbose_name='散布日')
name = models.CharField(max_length=100, blank=True, 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 = ['-date', '-id']
def __str__(self):
label = self.name.strip() or f'{self.date}'
return f'{self.year} {label}'
class SpreadingSessionItem(models.Model):
"""散布実績明細:圃場×肥料ごとの実績"""
session = models.ForeignKey(
SpreadingSession,
on_delete=models.CASCADE,
related_name='items',
verbose_name='散布実績',
)
field = models.ForeignKey(
'fields.Field', on_delete=models.PROTECT, verbose_name='圃場'
)
fertilizer = models.ForeignKey(
Fertilizer, on_delete=models.PROTECT, verbose_name='肥料'
)
actual_bags = models.DecimalField(max_digits=10, decimal_places=4, verbose_name='実散布袋数')
planned_bags_snapshot = models.DecimalField(
max_digits=10,
decimal_places=4,
verbose_name='計画袋数スナップショット',
)
delivered_bags_snapshot = models.DecimalField(
max_digits=10,
decimal_places=4,
verbose_name='運搬済み袋数スナップショット',
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = '散布実績明細'
verbose_name_plural = '散布実績明細'
unique_together = [['session', 'field', 'fertilizer']]
ordering = ['field__display_order', 'field__id', 'fertilizer__name']
def __str__(self):
return (
f'{self.session} / {self.field.name} / '
f'{self.fertilizer.name}: {self.actual_bags}'
)