108 lines
3.5 KiB
Python
108 lines
3.5 KiB
Python
from django.db import models
|
|
from django.urls import reverse
|
|
|
|
|
|
class ProblemCase(models.Model):
|
|
AREA_SALES = "sales"
|
|
AREA_OPERATIONS = "operations"
|
|
AREA_FINANCE = "finance"
|
|
AREA_MARKETING = "marketing"
|
|
AREA_PRODUCT = "product"
|
|
AREA_PEOPLE = "people"
|
|
AREA_OTHER = "other"
|
|
|
|
BUSINESS_AREA_CHOICES = [
|
|
(AREA_SALES, "Penjualan"),
|
|
(AREA_OPERATIONS, "Operasional"),
|
|
(AREA_FINANCE, "Keuangan"),
|
|
(AREA_MARKETING, "Marketing"),
|
|
(AREA_PRODUCT, "Produk/Layanan"),
|
|
(AREA_PEOPLE, "Tim & SDM"),
|
|
(AREA_OTHER, "Lainnya"),
|
|
]
|
|
|
|
STATUS_DRAFT = "draft"
|
|
STATUS_ANALYZED = "analyzed"
|
|
STATUS_CHOICES = [
|
|
(STATUS_DRAFT, "Draft"),
|
|
(STATUS_ANALYZED, "Sudah dianalisis"),
|
|
]
|
|
|
|
title = models.CharField("judul kasus", max_length=160)
|
|
description = models.TextField("deskripsi masalah")
|
|
business_area = models.CharField(
|
|
"area bisnis", max_length=32, choices=BUSINESS_AREA_CHOICES, default=AREA_SALES
|
|
)
|
|
urgency = models.PositiveSmallIntegerField("urgensi", default=3)
|
|
priority_score = models.PositiveSmallIntegerField("skor prioritas", default=0)
|
|
financial_impact = models.CharField("dampak finansial", max_length=32, default="Sedang")
|
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_DRAFT)
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
class Meta:
|
|
ordering = ["-created_at"]
|
|
verbose_name = "Problem Case"
|
|
verbose_name_plural = "Problem Cases"
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
def get_absolute_url(self):
|
|
return reverse("case_detail", kwargs={"pk": self.pk})
|
|
|
|
|
|
class RootCause(models.Model):
|
|
problem = models.ForeignKey(
|
|
ProblemCase, related_name="root_causes", on_delete=models.CASCADE
|
|
)
|
|
parent = models.ForeignKey(
|
|
"self", related_name="children", null=True, blank=True, on_delete=models.CASCADE
|
|
)
|
|
factor = models.CharField(max_length=120)
|
|
contribution_score = models.PositiveSmallIntegerField(default=70)
|
|
why_chain = models.TextField()
|
|
|
|
class Meta:
|
|
ordering = ["-contribution_score", "factor"]
|
|
|
|
def __str__(self):
|
|
return f"{self.factor} ({self.contribution_score}%)"
|
|
|
|
|
|
class SolutionOption(models.Model):
|
|
problem = models.ForeignKey(
|
|
ProblemCase, related_name="solutions", on_delete=models.CASCADE
|
|
)
|
|
title = models.CharField(max_length=160)
|
|
impact = models.PositiveSmallIntegerField(default=70)
|
|
efficiency = models.PositiveSmallIntegerField(default=70)
|
|
speed = models.PositiveSmallIntegerField(default=70)
|
|
low_risk = models.PositiveSmallIntegerField(default=70)
|
|
decision_score = models.DecimalField(max_digits=5, decimal_places=2, default=0)
|
|
success_rate = models.PositiveSmallIntegerField(default=70)
|
|
rank = models.PositiveSmallIntegerField(default=1)
|
|
rationale = models.TextField()
|
|
|
|
class Meta:
|
|
ordering = ["rank", "-decision_score"]
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
|
|
class ActionPlanStep(models.Model):
|
|
solution = models.ForeignKey(
|
|
SolutionOption, related_name="action_steps", on_delete=models.CASCADE
|
|
)
|
|
day_index = models.PositiveSmallIntegerField()
|
|
title = models.CharField(max_length=120)
|
|
task = models.TextField()
|
|
is_done = models.BooleanField(default=False)
|
|
|
|
class Meta:
|
|
ordering = ["day_index"]
|
|
|
|
def __str__(self):
|
|
return f"Hari {self.day_index}: {self.title}"
|