from django.contrib.auth import get_user_model from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from .models import AuditLog, Notification, Risk, ResidualRisk def model_diff(old, new, fields=None): """ Compare two model instances and return a dict of changed fields. - old: previous model instance (from DB) - new: updated model instance (unsaved) - fields: optional list of fields to check """ changes = {} opts = new._meta if fields is None: fields = [f.name for f in opts.fields] for field_name in fields: old_value = getattr(old, field_name, None) new_value = getattr(new, field_name, None) if old_value != new_value: changes[field_name] = {"old": old_value, "new": new_value} return changes def check_risk_followups(): """ Check if follow ups need attention and create notifications. Ensures no duplicate notifications per risk per day """ today = now().date() risks = Risk.objects.filter(follow_up__lte=today).select_related("owner") for risk in risks: # Risk-Status auf review_required setzen (nicht überschreiben, wenn bereits closed) if risk.status != "closed" and risk.status != "review_required": Risk.objects.filter(pk=risk.pk).update(status="review_required") # ResidualRisk-Objekt sicherstellen und Review-Flag setzen resid, created = ResidualRisk.objects.get_or_create(risk=risk) if not resid.review_required: resid.review_required = True resid.save() # Notification an Stakeholder message = _("Follow-up reached: review required for risk '{t}'").format(t=risk.title) notification, created = Notification.objects.get_or_create( user=risk.owner, message=message, defaults={"read": False, "sent": False}, ) if created: AuditLog.objects.create( user=None, action="create", model="Notification", object_id=notification.pk, changes={"message": notification.message, "user": risk.owner.username if risk.owner else None}, )