from __future__ import annotations from apps.farms.models import Cycle from apps.operations.models import ManualInput DAILY_TO_TOTAL = ( ("mortality_manual", "mortality_manual_total"), ("feed_in_manual", "feed_in_manual_total"), ("feed_use_manual", "feed_use_manual_total"), ("feed_out_manual", "feed_out_manual_total"), ("harvest_manual", "harvest_manual_total"), ("harvest_weight_manual", "harvest_weight_manual_total"), ) SKIPPED_DERIVED_FIELDS = ( "average_harvest_day_manual", "average_harvest_weight_manual", "fcr_manual", "eef_manual", ) def recompute_manual_totals(cycle: Cycle) -> None: running = {total: 0 for _, total in DAILY_TO_TOTAL} rows = list(ManualInput.objects.filter(cycle=cycle).order_by("date", "pk")) for row in rows: changed: list[str] = [] for daily, total in DAILY_TO_TOTAL: running[total] += getattr(row, daily) or 0 if getattr(row, total) != running[total]: setattr(row, total, running[total]) changed.append(total) for field in SKIPPED_DERIVED_FIELDS: if getattr(row, field) != 0: setattr(row, field, 0) changed.append(field) if changed: row.save(update_fields=[*changed, "updated_at"])