施肥散布実績機能を実装し運搬・作業記録・在庫連携を追加
This commit is contained in:
65
backend/apps/fertilizer/services.py
Normal file
65
backend/apps/fertilizer/services.py
Normal file
@@ -0,0 +1,65 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import Sum
|
||||
|
||||
from apps.materials.models import StockTransaction
|
||||
from apps.workrecords.services import sync_spreading_work_record
|
||||
from .models import FertilizationEntry, SpreadingSessionItem
|
||||
|
||||
|
||||
def sync_actual_bags_for_pairs(year, field_fertilizer_pairs):
|
||||
pairs = {
|
||||
(int(field_id), int(fertilizer_id))
|
||||
for field_id, fertilizer_id in field_fertilizer_pairs
|
||||
}
|
||||
if not pairs:
|
||||
return
|
||||
|
||||
for field_id, fertilizer_id in pairs:
|
||||
total = (
|
||||
SpreadingSessionItem.objects.filter(
|
||||
session__year=year,
|
||||
field_id=field_id,
|
||||
fertilizer_id=fertilizer_id,
|
||||
).aggregate(total=Sum('actual_bags'))['total']
|
||||
)
|
||||
FertilizationEntry.objects.filter(
|
||||
plan__year=year,
|
||||
field_id=field_id,
|
||||
fertilizer_id=fertilizer_id,
|
||||
).update(actual_bags=total)
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def sync_spreading_session_side_effects(session, field_fertilizer_pairs):
|
||||
sync_actual_bags_for_pairs(session.year, field_fertilizer_pairs)
|
||||
sync_stock_uses_for_spreading_session(session)
|
||||
sync_spreading_work_record(session)
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def sync_stock_uses_for_spreading_session(session):
|
||||
StockTransaction.objects.filter(spreading_item__session=session).delete()
|
||||
|
||||
session_items = session.items.select_related('fertilizer__material')
|
||||
for item in session_items:
|
||||
material = getattr(item.fertilizer, 'material', None)
|
||||
if material is None:
|
||||
continue
|
||||
StockTransaction.objects.create(
|
||||
material=material,
|
||||
transaction_type=StockTransaction.TransactionType.USE,
|
||||
quantity=item.actual_bags,
|
||||
occurred_on=session.date,
|
||||
note=f'散布実績「{session.name.strip() or session.date}」',
|
||||
fertilization_plan=None,
|
||||
spreading_item=item,
|
||||
)
|
||||
|
||||
|
||||
def to_decimal_or_zero(value):
|
||||
try:
|
||||
return Decimal(str(value))
|
||||
except Exception:
|
||||
return Decimal('0')
|
||||
Reference in New Issue
Block a user