ISO-27001-Risk-Management/risks/models/residual_risk.py
2025-09-22 08:35:11 +02:00

45 lines
No EOL
1.7 KiB
Python

from django.db import models
from django.utils.translation import gettext_lazy as _
from .risk import Risk
# ---------------------------------------------------------------------------
# Residual Risk
# ---------------------------------------------------------------------------
class ResidualRisk(models.Model):
"""Residual risk after implementing controls."""
class Meta:
verbose_name = _("Residual Risk")
verbose_name_plural = _("Residual Risks")
risk = models.OneToOneField("Risk", on_delete=models.CASCADE, related_name="residual_risk")
likelihood = models.IntegerField(choices=Risk.LIKELIHOOD_CHOICES, default=1)
impact = models.IntegerField(choices=Risk.IMPACT_CHOICES, default=1)
score = models.IntegerField(editable=False)
level = models.CharField(max_length=50, editable=False)
review_required = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
if self.pk:
old = ResidualRisk.objects.get(pk=self.pk)
if old.likelihood != self.likelihood or old.impact != self.impact:
self.review_required = True
self.status = "review_required"
# Calculate residual risk score and level
self.score = self.likelihood * self.impact
if self.score <= 4:
self.level = "Low"
elif self.score <= 8:
self.level = "Medium"
elif self.score <= 12:
self.level = "High"
else:
self.level = "Critical"
super().save(*args, **kwargs)
def __str__(self):
return f"Residual Risk for {self.risk.title} (Score: {self.score}, Level: {self.level})"