from django.db import transaction from .models import Plan, PlanVarietyChange class _NoChange: pass NO_CHANGE = _NoChange() @transaction.atomic def update_plan_with_variety_tracking( plan: Plan, *, crop=NO_CHANGE, variety=NO_CHANGE, notes=NO_CHANGE, reason: str = '', ): old_variety = plan.variety updated_fields = [] if crop is not NO_CHANGE: plan.crop = crop updated_fields.append('crop') if variety is not NO_CHANGE: plan.variety = variety updated_fields.append('variety') if notes is not NO_CHANGE: plan.notes = notes updated_fields.append('notes') if updated_fields: plan.save(update_fields=updated_fields) if variety is not NO_CHANGE and _get_variety_id(old_variety) != _get_variety_id(plan.variety): handle_plan_variety_change(plan, old_variety=old_variety, new_variety=plan.variety, reason=reason) return plan @transaction.atomic def handle_plan_variety_change(plan: Plan, *, old_variety, new_variety, reason: str = ''): if _get_variety_id(old_variety) == _get_variety_id(new_variety): return None change = PlanVarietyChange.objects.create( field=plan.field, year=plan.year, plan=plan, old_variety=old_variety, new_variety=new_variety, reason=reason, ) process_plan_variety_change(change) return change def process_plan_variety_change(change: PlanVarietyChange): from apps.fertilizer.services import move_unspread_entries_for_variety_change moved_count = move_unspread_entries_for_variety_change(change) if moved_count != change.moved_entry_count: change.moved_entry_count = moved_count change.save(update_fields=['moved_entry_count']) return change def _get_variety_id(variety): return getattr(variety, 'id', None)