I'm developing a project management application in Django that requires a somewhat linear response process involving different groups of users (as in Django auth Groups). Each step in the response process has several response options (most options unique to the step) and is assigned to a user within a particular group. The next step in the process is determined by the user's response, and occasionally additional information may need to be requested from one of the project's members.
The problem is that my current implementation seems rather cumbersome and I am certain there is a better way to keep track of the response process. I was hoping someone could provide some insight into a more robust solution.
As a simple example, consider a Project with the following user Groups: Sales Rep, Sales Manager, and Project Manager. The models currently looks like this:
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)
Here's a simple overview of how the process might work:
- Sales Rep creates a new project and it is assigned to Sales Manager
- Sales Manager is presented with the following options:
(a) approve the project or
(b) request more information from the Sales Rep - If the project is approved, assign to Project Manager who is presented with the following options:
(a) commence the project
(b) reject the project
(c) request more information from the Sales Rep or Sales Manager - If more information is requested from a user, the project is assigned to that user and they just need to provide a textbox response. However, once their response has been received, the project needs to return to the previous step (this is why I keep track of current_step and previous_step above). In this example, if Project Manager requests more information from the Sales Rep, once the Sales Rep responds the project should be assigned back to the Project Manager with the same response options that he had before (commence, reject, request more information).
The full process has about 10 or so steps like these.
To complicate things, I also need to be able to display the response chosen for each step. For example, if the Sales Manager approves the project, it should display "Sales Manager approved the project" along with any comments they may have. The model looks like this:
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)
Right now the logic for each response action is hard coded in the view, and there's no formal relationship between one step and another. I feel like there's a better model structure or data structure I should be using to keep track of this workflow, but I've been working with the current system for so long that I'm having trouble thinking about it differently. Any insight or inspiration would be greatly appreciated! Let me know if I need to clarify anything.