52 lines
No EOL
1.9 KiB
Python
52 lines
No EOL
1.9 KiB
Python
from django.db import models
|
|
from django.utils.translation import gettext_lazy as _
|
|
from .likelihood_choice import LikelihoodChoice
|
|
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.ForeignKey(
|
|
LikelihoodChoice,
|
|
on_delete=models.PROTECT,
|
|
verbose_name=_("Likelihood"),
|
|
related_name="residual_risks",
|
|
)
|
|
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.value * 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})" |