123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- from __future__ import unicode_literals
- from django.db import models
- from django.utils import timezone
- # Create your models here.
- class Project(models.Model):
- '''
- Represents a project comprised of several tasks, a beginning and an end,
- and metadata such as scope, resources allocated, etc.
- Models Task, Risk, Issue and Status all depend on this as a foreign key.
- '''
- name = models.CharField(max_length=255)
- scope = models.TextField()
- resources = models.TextField(blank=True)
- def __unicode__(self):
- return self.name
- class Task(models.Model):
- '''
- Represents a single task within an overall project.
- Can have a status between not started, work in progress and complete.
- Automatically gets flagged as delayed.
- '''
- title = models.CharField(max_length=255)
- description = models.TextField()
- start = models.DateField(default=timezone.now)
- end = models.DateField(default=timezone.now)
- STATUSES = (
- ('NS', 'Not started'),
- ('ST', 'Work in progress'),
- ('CO', 'Complete'),
- )
- status = models.CharField(
- max_length=2,
- choices=STATUSES,
- default='NS',
- )
- project = models.ForeignKey(Project, on_delete=models.CASCADE, editable=False)
- def is_late(self):
- '''
- Tasks that should have started but didn't, or that should have ended
- but didn't get flagged here.
- FIXME: these perform some kind of conversion I can't seem to match.
- '''
- if self.status != 'CO':
- return self.start > timezone.now() or self.end > timezone.now()
- else:
- return False
- def __unicode__(self):
- return self.title
- # Issues, Risks, etc.
- class Risk(models.Model):
- '''
- Represents a single project risk containing a description, impact,
- urgency, response strategy, and response plan due date.
- '''
- IMPACT_ROSTER = (
- ('1', 'Low impact'),
- ('2', 'Medium impact'),
- ('3', 'Severe impact'),
- )
- RESPONSE_ROSTER = (
- ('AC', 'Accept risk'),
- ('MT', 'Mitigate risk'),
- ('EL', 'Eliminate risk'),
- )
- STATUSES = (
- ('NS', "Not started"),
- ('WP', "Work in progress"),
- ('CO', "Closed"),
- )
-
- name = models.CharField(max_length=100)
- description = models.TextField()
- impact = models.CharField(
- max_length=1,
- choices=IMPACT_ROSTER,
- )
- response = models.CharField(
- max_length=2,
- choices=RESPONSE_ROSTER,
- )
- response_plan = models.TextField()
- response_plan_due = models.DateField(default=timezone.now)
- status = models.CharField(
- max_length=2,
- choices=STATUSES,
- default='NS'
- )
- project = models.ForeignKey(Project, on_delete=models.CASCADE, editable=False)
- def __unicode__(self):
- return "[%s] - %s (%s)" % (self.project, self.name, self.impact)
- class Issue(models.Model):
- '''
- A single project issue with description, severity, action plan and action
- plan due date.
- '''
- SEVERITY_ROSTER = (
- ('1', 'Low impact'),
- ('2', 'Medium impact'),
- ('3', 'Severe impact'),
- )
- STATUSES = (
- ('NS', "Open"),
- ('WP', "Work in progress"),
- ('CO', "Closed"),
- )
- name = models.CharField(max_length=255)
- description = models.TextField()
- severity = models.CharField(
- max_length=1,
- choices=SEVERITY_ROSTER
- )
- status = models.CharField(
- max_length=2,
- choices=STATUSES,
- default='NS'
- )
- action_plan = models.TextField()
- action_plan_due = models.DateField(default=timezone.now)
- project = models.ForeignKey(Project, on_delete=models.CASCADE, editable=False)
- def __unicode__(self):
- return "[%s] - %s (%s)" % (self.project, self.name, self.severity)
- class Status(models.Model):
- '''
- Represents a status issued for a project with detailed status, next moves,
- and individual statuses for cost, time and quality dimensions.
- '''
- STATUSES = (
- ('G', 'Green'),
- ('A', 'Amber'),
- ('R', 'Red'),
- )
- date = models.DateField(default=timezone.now)
- status = models.TextField()
- next_moves = models.TextField()
- cost = models.CharField(
- max_length=1,
- choices=STATUSES,
- default='G',
- )
- time = models.CharField(
- max_length=1,
- choices=STATUSES,
- default='G',
- )
- quality = models.CharField(
- max_length=1,
- choices=STATUSES,
- default='G',
- )
- project = models.ForeignKey(Project, on_delete=models.CASCADE)
- def __unicode__(self):
- return "Status for '%s' on %s" % (self.project, self.date)
- class Meta:
- verbose_name_plural = "statuses"
|