Django: Как отслеживать линейный (но гибкий) рабочий процесс управления проектами? - PullRequest
3 голосов
/ 19 августа 2010

Я разрабатываю приложение для управления проектами в Django, которое требует несколько линейного процесса ответа с участием различных групп пользователей (как в Django auth Groups).Каждый шаг в процессе ответа имеет несколько опций ответа (большинство опций уникально для шага) и назначается пользователю в определенной группе.Следующий шаг в этом процессе определяется ответом пользователя, и иногда может потребоваться дополнительная информация у одного из участников проекта.

Проблема в том, что моя текущая реализация кажется довольно громоздкой, и я уверен, что тамэто лучший способ отслеживать процесс ответа.Я надеялся, что кто-то сможет дать представление о более надежном решении.

В качестве простого примера рассмотрим проект со следующими группами пользователей: торговый представитель, менеджер по продажам и менеджер проекта.Модели в настоящее время выглядят так:

class Project(models.Model):  
    assigned_to = models.ForeignKey(User, related_name="projects_assigned_to") #Indicates which user needs to respond next.  Will be sales_rep, sales_mgr, or project_mgr.
    sales_rep = models.ForeignKey(User, related_name="sales_rep_projects") #choices limited to "Sales Rep" Group  
    sales_mgr = models.ForeignKey(User, related_name="sales_mgr_projects") #choices limited to "Sales Manager" Group 
    project_mgr = models.ForeignKey(User, related_name="project_mgr_projects") #choices limited to "Project Manager" Group
    current_step = models.ForeignKey(Step, related_name="projects_with_current_step")
    previous_step = models.ForeignKey(Step, related_name="projects_with_previous_step")
    status = models.ForeignKey(Status) #Automatically assigned according to the user's response.  Includes things like "On Track", "On Hold", "Rejected", "Accepted", etc.

class Step(models.Model):
    name = models.CharField(max_length=50) 

class Status(models.Model):
    name = models.CharField(max_length=50) 

Вот простой обзор того, как этот процесс может работать:

  1. Торговый представитель создает новый проект и назначает его менеджеру по продажам
  2. Менеджер по продажам представлен следующими опциями:
    (a) утвердить проект или
    (b) запросить дополнительную информацию у торгового представителя
  3. Если проект утвержден, назначьтеМенеджеру проекта, которому предоставляются следующие опции:
    (a) начать проект
    (b) отклонить проект
    (c) запросить дополнительную информацию у торгового представителя или менеджера по продажам
  4. Если от пользователя запрашивается дополнительная информация, ему назначается проект, и ему просто нужно предоставить ответ в текстовом поле.Однако, как только их ответ получен, проект должен вернуться к предыдущему шагу (вот почему я отслеживаю current_step и previous_step выше).В этом примере, если менеджер проекта запрашивает дополнительную информацию у торгового представителя, после того, как торговый представитель ответит, проект должен быть возвращен менеджеру проекта с теми же вариантами ответа, которые у него были ранее (начать, отклонить, запросить дополнительную информацию).

Полный процесс содержит около 10 или около того шагов, подобных этим.

Чтобы усложнить ситуацию, мне также нужно иметь возможность отображать ответ, выбранный для каждого шага.Например, если менеджер по продажам одобряет проект, он должен отображать «Менеджер по продажам одобрил проект» вместе с любыми комментариями, которые они могут иметь.Модель выглядит следующим образом:

class Response(models.Model):
    comment = models.TextField()
    response_action = models.ForeignKey(ResponseAction)
    submitted = models.DateTimeField()

class ResponseAction(models.Model):
     """ I.e. 'Sales Manager approved the project', 'Project Manager commenced the project'"""  
     name = models.CharField(max_length=100)

Прямо сейчас логика для каждого ответного действия жестко запрограммирована в представлении, и нет формальной связи между одним шагом и другим.Я чувствую, что есть лучшая структура модели или структура данных, которую я должен использовать, чтобы отслеживать этот рабочий процесс, но я работаю с текущей системой так долго, что мне трудно думать об этом по-другому.Любое понимание или вдохновение будет принята с благодарностью!Дайте мне знать, если мне нужно что-то уточнить.

1 Ответ

1 голос
/ 19 августа 2010

Используйте модель Step. Вы можете сохранить возможные последующие шаги в качестве внешних ключей. Таким образом, вы можете редактировать поток, изменяя данные (например, используя администратор вместо жесткого кодирования). Может быть что-то вроде:

class Step(models.Model):
    name = models.CharField(max_length=50)
    responsible_role = models.CharField(max_length=50) # this contains 'sales_rep', 'sales_mgr' etc
    allowed_actions = models.ManyToManyField('AllowedAction')

class AllowedAction(models.Model):
    name = models.CharField(max_length=50)
    next_step = models.ForeignKey('Step') # the next step, if this action is chosen

Отделение фактической истории проекта от другой модели:

class ProjectHistoryStep(models.Model):
    timestamp = models.DateTimeField()
    step = models.ForeignKey('Step')
    project = models.ForeignKey('Project')  

Вы можете использовать эту модель для отслеживания фактического прогресса ваших проектов (не забывайте, что модели имеют get_next_by_FOO ).

Вам понадобится только 1 представление, которое обрабатывает всю логику (ему нужно просто вызвать какой-то метод класса Project для выполнения реальной работы) - проверить, в каком состоянии находится проект (последний ProjectHistoryStep для этого проекта), и каким было действие пользователя, и действовать соответственно.

...