Need help/suggestion on a model

Need to create Models in django for a task management app. The columns for planned_task are

  1. Task Area
  2. Task Type
  3. Task Assigned Date
  4. Assigned to
  5. Supporting member

This is the model for task plan(tasks will be followed according to this schedule)

class PlanTask(models.Model):

       id = models.AutoField(primary_key=True)
       task_area = models.CharField(max_length=255, null=False)
       task_type = models.CharField(max_length=255, null=False)
       task_assigned_date = models.DateField(null=False)
       assigned_to = models.ForeignKey(User, null=True, blank=True,on_delete=models.DO_NOTHING)
       supporting_member = models.ForeignKey(User, null=True, blank=True, on_delete=models.DO_NOTHING)

       planned_start_date = models.DateField(null=True, blank=True)
       planned_planning_start = models.DateField(null=True, blank=True)
       planned_planning_end = models.DateField(null=True, blank=True)
       planned_field_work_start = models.DateField(null=True, blank=True)
       planned_field_work_end = models.DateField(null=True, blank=True)
       planned_reporting_start = models.DateField(null=True, blank=True)
       planned_reporting_end = models.DateField(null=True, blank=True)
       planned_approval_start = models.DateField(null=True, blank=True)
       planned_approval_end = models.DateField(null=True, blank=True)
       planned_end_date = models.DateField(null=True, blank=True)

This is the model for Actual task

class ActualTask(models.Model):
    id = models.AutoField(primary_key=True)
    task_area = models.ForeignKey(Plan, null=True, blank=True, on_delete=models.CASCADE)
    STATUS_CHOICES = [
        ('Assigned', 'Assigned'),
        ('WIP', 'WIP'),
        ('Completed', 'Completed'),
    ]
    status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='Assigned', null=False)

    planning_stage = models.CharField(max_length=255, null=True, blank=True)
    research_planning = models.DecimalField(max_digits=5, decimal_places=2,
                                            choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                            validators=[MaxValueValidator(25)], null=True, blank=True)
    task_plan = models.DecimalField(max_digits=5, decimal_places=2,
                                     choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                     validators=[MaxValueValidator(25)], null=True, blank=True)
    initial_task_meeting = models.DecimalField(max_digits=5, decimal_places=2,
                                                choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                                validators=[MaxValueValidator(25)], null=True, blank=True)
    process_walkover = models.DecimalField(max_digits=5, decimal_places=2,
                                           choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                           validators=[MaxValueValidator(25)], null=True, blank=True)

    @property
    def planning_progress(self):
        return (self.research_planning or 0) + (self.task_plan or 0) + (self.initial_task_meeting or 0) + (
                    self.process_walkover or 0)

    field_work_stage = models.CharField(max_length=255, null=True, blank=True)
    documents_verification = models.DecimalField(max_digits=5, decimal_places=2,
                                                 choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                                 validators=[MaxValueValidator(25)], null=True, blank=True)
    research_work_data_analysis = models.DecimalField(max_digits=5, decimal_places=2,
                                                      choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                                      validators=[MaxValueValidator(25)], null=True, blank=True)
    research_work_field = models.DecimalField(max_digits=5, decimal_places=2,
                                              choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                              validators=[MaxValueValidator(25)], null=True, blank=True)
    query_clarification = models.DecimalField(max_digits=5, decimal_places=2,
                                              choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                              validators=[MaxValueValidator(25)], null=True, blank=True)

    @property
    def field_work_progress(self):
        return (self.documents_verification or 0) + (self.research_work_data_analysis or 0) + (
                    self.research_work_field or 0) + (self.query_clarification or 0)

    reporting_stage = models.CharField(max_length=255, null=True, blank=True)
    drafting_report = models.DecimalField(max_digits=5, decimal_places=2,
                                          choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                          validators=[MaxValueValidator(25)], null=True, blank=True)
    task_presentation = models.DecimalField(max_digits=5, decimal_places=2,
                                             choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                             validators=[MaxValueValidator(25)], null=True, blank=True)
    taskee_feedback_pending = models.DecimalField(max_digits=5, decimal_places=2,
                                                   choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                                   validators=[MaxValueValidator(25)], null=True, blank=True)
    final_presentation = models.DecimalField(max_digits=5, decimal_places=2,
                                             choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                             validators=[MaxValueValidator(25)], null=True, blank=True)

    @property
    def reporting_progress(self):
        return (self.drafting_report or 0) + (self.task_presentation or 0) + (self.taskee_feedback_pending or 0) + (
                    self.final_presentation or 0)

    approval_stage = models.CharField(max_length=255, null=True, blank=True)
    mgmt_approval = models.DecimalField(max_digits=5, decimal_places=2,
                                        choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                        validators=[MaxValueValidator(25)], null=True, blank=True)
    ic_to_taskee = models.DecimalField(max_digits=5, decimal_places=2,
                                        choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                        validators=[MaxValueValidator(25)], null=True, blank=True)
    gr_to_taskee = models.DecimalField(max_digits=5, decimal_places=2,
                                        choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                        validators=[MaxValueValidator(25)], null=True, blank=True)
    completed = models.DecimalField(max_digits=5, decimal_places=2,
                                    choices=[(0, '0'), (10, '10'), (20, '20'), (25, '25')],
                                    validators=[MaxValueValidator(25)], null=True, blank=True)

    @property
    def approval_progress(self):
        return (self.mgmt_approval or 0) + (self.ic_to_taskee or 0) + (self.gr_to_taskee or 0) + (self.completed or 0)

    @property
    def overall_progress(self):
        return (self.planning_progress * 0.15) + (self.field_work_progress * 0.5) + (self.reporting_progress * 0.25) + (
                    self.approval_progress * 0.1)

    actual_start_date = models.DateField(null=True, blank=True)
    actual_planning_start = models.DateField(null=True, blank=True)
    actual_planning_end = models.DateField(null=True, blank=True)
    delay_planning = models.IntegerField(default=0)
    actual_field_work_start = models.DateField(null=True, blank=True)
    actual_field_work_end = models.DateField(null=True, blank=True)
    delay_field_work = models.IntegerField(default=0)
    actual_reporting_start = models.DateField(null=True, blank=True)
    actual_reporting_end = models.DateField(null=True, blank=True)
    delay_reporting = models.IntegerField(default=0)
    actual_approval_start = models.DateField(null=True, blank=True)
    actual_approval_end = models.DateField(null=True, blank=True)
    delay_approval = models.IntegerField(default=0)
    actual_end_date = models.DateField(null=True, blank=True)
    delay = models.IntegerField(default=0)

    def save(self, *args, **kwargs):
        # Update actual dates and delays
        if self.status == 'WIP' and not self.actual_start_date:
            self.actual_start_date = timezone.now().date()
        if self.planning_progress > 0 and not self.actual_planning_start:
            self.actual_planning_start = timezone.now().date()
        if self.planning_progress == 100 and not self.actual_planning_end:
            self.actual_planning_end = timezone.now().date()
        if self.field_work_progress > 0 and not self.actual_field_work_start:
            self.actual_field_work_start = timezone.now().date()
        if self.field_work_progress == 100 and not self.actual_field_work_end:
            self.actual_field_work_end = timezone.now().date()
        if self.reporting_progress > 0 and not self.actual_reporting_start:
            self.actual_reporting_start = timezone.now().date()
        if self.reporting_progress == 100 and not self.actual_reporting_end:
            self.actual_reporting_end = timezone.now().date()
        if self.approval_progress > 0 and not self.actual_approval_start:
            self.actual_approval_start = timezone.now().date()
        if self.approval_progress == 100 and not self.actual_approval_end:
            self.actual_approval_end = timezone.now().date()
        if self.status == 'Completed' and not self.actual_end_date:
            self.actual_end_date = timezone.now().date()

        # Calculate delays
        # Assuming planned_* fields are provided and should be datetime.date objects
        today = timezone.now().date()
        if hasattr(self, 'planned_planning_end') and self.planned_planning_end:
            self.delay_planning = max((today - self.planned_planning_end).days,
                                      0) if self.actual_planning_end is None else max(
                (self.actual_planning_end - self.planned_planning_end).days, 0)
        if hasattr(self, 'planned_field_work_end') and self.planned_field_work_end:
            self.delay_field_work = max((today - self.planned_field_work_end).days,
                                        0) if self.actual_field_work_end is None else max(
                (self.actual_field_work_end - self.planned_field_work_end).days, 0)
        if hasattr(self, 'planned_reporting_end') and self.planned_reporting_end:
            self.delay_reporting = max((today - self.planned_reporting_end).days,
                                       0) if self.actual_reporting_end is None else max(
                (self.actual_reporting_end - self.planned_reporting_end).days, 0)
        if hasattr(self, 'planned_approval_end') and self.planned_approval_end:
            self.delay_approval = max((today - self.planned_approval_end).days,
                                      0) if self.actual_approval_end is None else max(
                (self.actual_approval_end - self.planned_approval_end).days, 0)

        self.delay = self.delay_planning + self.delay_field_work + self.delay_reporting + self.delay_approval

        super().save(*args, **kwargs)

    def __str__(self):
        return f"task {self.id}: {self.task_area}"

My idea is that when the team leader assigns a task it goes to the assigned list for the particular team member. Then they can add the task to their work-in-progress list. If they completed it then it will go to their completed list.(and I also want to archive the tasks once the year is completed.)

PlanTask will be a reference for ActualTasks, and I have to link PlanTask model with ActualTasks model so that we can track delay in the progress.

The “Assigned to” and “Supporting member” are foreign keys taken from Users model. But when I gave these two, I got a error

Reverse accessor ‘User.plan_set’ for ‘task_management.Plan.assigned_to’ clashes with reverse accessor for ‘task_management.Plan.supporting_member’ HINT: Add or change a related_name argument to the definition

Is this linking PlanTask with ActualTasks possible? or is there any easy way to do this?