Removed transitions and move to a Node based workflow element
This commit is contained in:
@@ -9,11 +9,9 @@ from .permissions import (PERMISSION_WORKFLOW_SETUP_VIEW,
|
||||
PERMISSION_WORKFLOW_SETUP_CREATE, PERMISSION_WORKFLOW_SETUP_EDIT,
|
||||
PERMISSION_WORKFLOW_SETUP_DELETE, PERMISSION_STATE_SETUP_VIEW,
|
||||
PERMISSION_STATE_SETUP_CREATE, PERMISSION_STATE_SETUP_EDIT,
|
||||
PERMISSION_STATE_SETUP_DELETE, PERMISSION_TRANSITION_SETUP_VIEW,
|
||||
PERMISSION_TRANSITION_SETUP_CREATE, PERMISSION_TRANSITION_SETUP_EDIT,
|
||||
PERMISSION_TRANSITION_SETUP_DELETE)
|
||||
from .models import (Workflow, State, Transition, WorkflowState,
|
||||
WorkflowStateTransition)
|
||||
PERMISSION_STATE_SETUP_DELETE)
|
||||
|
||||
from .models import (Workflow, State, WorkflowState, WorkflowNode)
|
||||
|
||||
setup_workflow_list_link = Link(text=_(u'workflow list'), view='setup_workflow_list', sprite='chart_organisation', permissions=[PERMISSION_WORKFLOW_SETUP_VIEW])
|
||||
setup_workflow_create_link = Link(text=_(u'create new workflow'), view='setup_workflow_create', sprite='chart_organisation_add', permissions=[PERMISSION_WORKFLOW_SETUP_CREATE])
|
||||
@@ -33,34 +31,38 @@ setup_state_create_link = Link(text=_(u'create new state'), view='setup_state_cr
|
||||
setup_state_edit_link = Link(text=_(u'edit'), view='setup_state_edit', args='object.pk', sprite='transmit_edit', permissions=[PERMISSION_STATE_SETUP_EDIT])
|
||||
setup_state_delete_link = Link(text=_(u'delete'), view='setup_state_delete', args='object.pk', sprite='transmit_delete', permissions=[PERMISSION_STATE_SETUP_DELETE])
|
||||
|
||||
setup_transition_list_link = Link(text=_(u'transition list'), view='setup_transition_list', sprite='chart_line', permissions=[PERMISSION_TRANSITION_SETUP_VIEW])
|
||||
setup_transition_create_link = Link(text=_(u'create new transition'), view='setup_transition_create', sprite='chart_line_add', permissions=[PERMISSION_TRANSITION_SETUP_CREATE])
|
||||
setup_transition_edit_link = Link(text=_(u'edit'), view='setup_transition_edit', args='transition.pk', sprite='chart_line', permissions=[PERMISSION_TRANSITION_SETUP_EDIT])
|
||||
setup_transition_delete_link = Link(text=_(u'delete'), view='setup_transition_delete', args='transition.pk', sprite='chart_line_delete', permissions=[PERMISSION_TRANSITION_SETUP_DELETE])
|
||||
setup_workflow_node_list_link = Link(text=_(u'node list'), view='setup_workflow_node_list', args='workflow.pk', sprite='chart_line', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
#setup_workflow_node_create_link = Link(text=_(u'create new transition'), view='setup_transition_create', sprite='chart_line_add', permissions=[PERMISSION_TRANSITION_SETUP_CREATE])
|
||||
setup_workflow_node_edit_link = Link(text=_(u'edit'), view='setup_workflow_node_edit', args='workflow_node.pk', sprite='chart_line_edit', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
#setup_workflow_node_delete_link = Link(text=_(u'delete'), view='setup_transition_delete', args='transition.pk', sprite='chart_line_delete', permissions=[PERMISSION_TRANSITION_SETUP_DELETE])
|
||||
|
||||
bind_links(
|
||||
[
|
||||
Workflow, State, Transition, WorkflowStateTransition,
|
||||
Workflow, State,
|
||||
'setup_workflow_list', 'setup_workflow_create',
|
||||
'setup_state_list', 'setup_state_create',
|
||||
'setup_transition_list', 'setup_transition_create',
|
||||
#'setup_transition_list', 'setup_transition_create',
|
||||
'setup_transition_create',
|
||||
], [
|
||||
setup_workflow_list_link, setup_state_list_link, setup_transition_list_link
|
||||
setup_workflow_list_link, setup_state_list_link#, setup_transition_list_link
|
||||
], menu_name=u'form_header')
|
||||
|
||||
bind_links([Workflow], [setup_workflow_states_list_link, setup_workflow_edit_link, setup_workflow_delete_link])
|
||||
bind_links([Workflow], [setup_workflow_node_list_link, setup_workflow_states_list_link, setup_workflow_edit_link, setup_workflow_delete_link])
|
||||
bind_links([Workflow, 'setup_workflow_list', 'setup_workflow_create'], [setup_workflow_create_link], menu_name=u'secondary_menu')
|
||||
bind_links([WorkflowState, 'setup_workflow_states_list', 'setup_workflow_states_add'], [setup_workflow_states_add_link], menu_name=u'sidebar')
|
||||
|
||||
bind_links([State], [setup_state_edit_link, setup_state_delete_link])
|
||||
bind_links([State, 'setup_state_list', 'setup_state_create'], [setup_state_create_link], menu_name=u'secondary_menu')
|
||||
|
||||
bind_links([Transition], [setup_transition_edit_link, setup_transition_delete_link])
|
||||
bind_links([Transition, 'setup_transition_list', 'setup_transition_create'], [setup_transition_create_link], menu_name=u'secondary_menu')
|
||||
#bind_links([Transition], [setup_transition_edit_link, setup_transition_delete_link])
|
||||
#bind_links([Transition, 'setup_transition_list', 'setup_transition_create'], [setup_transition_create_link], menu_name=u'secondary_menu')
|
||||
|
||||
bind_links([WorkflowState], [setup_workflow_state_transitions_list_link, setup_workflow_states_edit_link, setup_workflow_states_remove_link])
|
||||
bind_links([WorkflowState], [setup_workflow_state_transition_add_link], menu_name=u'sidebar')
|
||||
#bind_links([WorkflowState], [setup_workflow_state_transitions_list_link, setup_workflow_states_edit_link, setup_workflow_states_remove_link])
|
||||
bind_links([WorkflowState], [setup_workflow_states_edit_link, setup_workflow_states_remove_link])
|
||||
|
||||
bind_links([WorkflowStateTransition], [setup_workflow_state_transition_edit_link])#, setup_transition_delete_link])
|
||||
#bind_links([WorkflowState], [setup_workflow_state_transition_add_link], menu_name=u'sidebar')
|
||||
#bind_links([WorkflowNode], [setup_workflow_state_transition_add_link], menu_name=u'sidebar')
|
||||
|
||||
bind_links([WorkflowNode], [setup_workflow_node_edit_link])#, setup_transition_delete_link])
|
||||
|
||||
register_setup(Link(text=_(u'workflows'), view='setup_workflow_list', icon='chart_organisation.png', permissions=[PERMISSION_WORKFLOW_SETUP_VIEW]))
|
||||
|
||||
@@ -3,11 +3,26 @@ from __future__ import absolute_import
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .models import Workflow, State, Transition, WorkflowState, WorkflowStateTransition
|
||||
from .models import Workflow, State, WorkflowState, WorkflowNode
|
||||
|
||||
|
||||
class NodeForm(forms.Form):
|
||||
def __init__(self, *args, **kwargs):
|
||||
#workflow = kwargs.pop('workflow')
|
||||
super(WorkflowStateSetupForm, self).__init__(*args, **kwargs)
|
||||
#self.fields['workflow'].initial = workflow
|
||||
#self.fields['workflow'].widget = forms.widgets.HiddenInput()
|
||||
print self.instance
|
||||
|
||||
#def choices(self, workflow):
|
||||
# return {
|
||||
## 'next_node': workflow.nodes.all()
|
||||
# }
|
||||
|
||||
|
||||
class WorkflowSetupForm(forms.ModelForm):
|
||||
class Meta:
|
||||
exclude = ('initial_node,')
|
||||
model = Workflow
|
||||
|
||||
|
||||
@@ -27,19 +42,29 @@ class WorkflowStateSetupForm(forms.ModelForm):
|
||||
model = WorkflowState
|
||||
|
||||
|
||||
class TransitionSetupForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Transition
|
||||
|
||||
|
||||
class WorkflowStateTransitionSetupForm(forms.ModelForm):
|
||||
class WorkflowNodeSetupForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
workflow_state = kwargs.pop('workflow_state')
|
||||
super(WorkflowStateTransitionSetupForm, self).__init__(*args, **kwargs)
|
||||
self.fields['workflow_state_source'].initial = workflow_state
|
||||
self.fields['workflow_state_source'].widget = forms.widgets.HiddenInput()
|
||||
workflow = kwargs.pop('workflow')
|
||||
super(WorkflowNodeSetupForm, self).__init__(*args, **kwargs)
|
||||
self.fields['workflow'].initial = workflow
|
||||
self.fields['workflow'].widget = forms.widgets.HiddenInput()
|
||||
|
||||
class Meta:
|
||||
model = WorkflowStateTransition
|
||||
model = WorkflowNode
|
||||
|
||||
#class TransitionSetupForm(forms.ModelForm):
|
||||
# class Meta:
|
||||
# model = Transition
|
||||
|
||||
|
||||
#class WorkflowStateTransitionSetupForm(forms.ModelForm):
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# workflow_state = kwargs.pop('workflow_state')
|
||||
# super(WorkflowStateTransitionSetupForm, self).__init__(*args, **kwargs)
|
||||
# self.fields['workflow_state_source'].initial = workflow_state
|
||||
# self.fields['workflow_state_source'].widget = forms.widgets.HiddenInput()
|
||||
#
|
||||
# class Meta:
|
||||
# model = WorkflowStateTransition
|
||||
|
||||
|
||||
|
||||
@@ -7,3 +7,13 @@ OPERAND_CHOICES = (
|
||||
(OPERAND_OR, _(u'or')),
|
||||
(OPERAND_AND, _(u'and'))
|
||||
)
|
||||
|
||||
NODE_TYPE_TASK = 'task'
|
||||
NODE_TYPE_START = 'start'
|
||||
NODE_TYPE_END = 'end'
|
||||
|
||||
NODE_TYPE_CHOICES = (
|
||||
(NODE_TYPE_TASK, _(u'Simple task')),
|
||||
(NODE_TYPE_START, _(u'Start')),
|
||||
(NODE_TYPE_END, _(u'End')),
|
||||
)
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'WorkflowInstance', fields ['object_id', 'content_type', 'workflow']
|
||||
db.delete_unique('workflows_workflowinstance', ['object_id', 'content_type_id', 'workflow_id'])
|
||||
|
||||
# Deleting model 'WorkflowStateAbilityGrant'
|
||||
db.delete_table('workflows_workflowstateabilitygrant')
|
||||
|
||||
# Deleting model 'WorkflowStateTransition'
|
||||
db.delete_table('workflows_workflowstatetransition')
|
||||
|
||||
# Deleting model 'WorkflowStateTransitionAbility'
|
||||
db.delete_table('workflows_workflowstatetransitionability')
|
||||
|
||||
# Deleting model 'Transition'
|
||||
db.delete_table('workflows_transition')
|
||||
|
||||
# Adding model 'WorkflowInstanceActiveState'
|
||||
db.create_table('workflows_workflowinstanceactivestate', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('workflow_instance', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['workflows.WorkflowInstance'])),
|
||||
('state', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['workflows.State'], null=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowInstanceActiveState'])
|
||||
|
||||
# Adding unique constraint on 'WorkflowInstanceActiveState', fields ['workflow_instance', 'state']
|
||||
db.create_unique('workflows_workflowinstanceactivestate', ['workflow_instance_id', 'state_id'])
|
||||
|
||||
# Adding model 'End'
|
||||
db.create_table('workflows_end', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('label', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['End'])
|
||||
|
||||
# Adding model 'WorkflowInstanceActiveNode'
|
||||
db.create_table('workflows_workflowinstanceactivenode', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('workflow_instance', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['workflows.WorkflowInstance'])),
|
||||
('workflow_node', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['workflows.WorkflowNode'])),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowInstanceActiveNode'])
|
||||
|
||||
# Adding model 'Start'
|
||||
db.create_table('workflows_start', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('label', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True)),
|
||||
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')(null=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['Start'])
|
||||
|
||||
# Adding model 'WorkflowNode'
|
||||
db.create_table('workflows_workflownode', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('workflow', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['workflows.Workflow'])),
|
||||
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
|
||||
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowNode'])
|
||||
|
||||
# Adding field 'Workflow.initial_node'
|
||||
db.add_column('workflows_workflow', 'initial_node', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='workflow_initial_node', null=True, to=orm['workflows.WorkflowNode']), keep_default=False)
|
||||
|
||||
# Deleting field 'WorkflowInstance.workflow_state'
|
||||
db.delete_column('workflows_workflowinstance', 'workflow_state_id')
|
||||
|
||||
# Adding unique constraint on 'WorkflowState', fields ['state', 'workflow']
|
||||
db.create_unique('workflows_workflowstate', ['state_id', 'workflow_id'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'WorkflowState', fields ['state', 'workflow']
|
||||
db.delete_unique('workflows_workflowstate', ['state_id', 'workflow_id'])
|
||||
|
||||
# Removing unique constraint on 'WorkflowInstanceActiveState', fields ['workflow_instance', 'state']
|
||||
db.delete_unique('workflows_workflowinstanceactivestate', ['workflow_instance_id', 'state_id'])
|
||||
|
||||
# Adding model 'WorkflowStateAbilityGrant'
|
||||
db.create_table('workflows_workflowstateabilitygrant', (
|
||||
('workflow_state', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_ability', to=orm['workflows.WorkflowState'])),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('content_type', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_ability_object', to=orm['contenttypes.ContentType'])),
|
||||
('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowStateAbilityGrant'])
|
||||
|
||||
# Adding model 'WorkflowStateTransition'
|
||||
db.create_table('workflows_workflowstatetransition', (
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('workflow_state_source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_transition_source', to=orm['workflows.WorkflowState'])),
|
||||
('transition', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_transition', to=orm['workflows.Transition'])),
|
||||
('workflow_state_destination', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_transition_destination', to=orm['workflows.WorkflowState'])),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowStateTransition'])
|
||||
|
||||
# Adding model 'WorkflowStateTransitionAbility'
|
||||
db.create_table('workflows_workflowstatetransitionability', (
|
||||
('ability', self.gf('django.db.models.fields.related.ForeignKey')(related_name='workflow_state_transition_ability', to=orm['workflows.Ability'])),
|
||||
('attribute_comparison_operand', self.gf('django.db.models.fields.CharField')(default='and', max_length=8)),
|
||||
('negate', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['WorkflowStateTransitionAbility'])
|
||||
|
||||
# Adding model 'Transition'
|
||||
db.create_table('workflows_transition', (
|
||||
('label', self.gf('django.db.models.fields.CharField')(max_length=128)),
|
||||
('description', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal('workflows', ['Transition'])
|
||||
|
||||
# Deleting model 'WorkflowInstanceActiveState'
|
||||
db.delete_table('workflows_workflowinstanceactivestate')
|
||||
|
||||
# Deleting model 'End'
|
||||
db.delete_table('workflows_end')
|
||||
|
||||
# Deleting model 'WorkflowInstanceActiveNode'
|
||||
db.delete_table('workflows_workflowinstanceactivenode')
|
||||
|
||||
# Deleting model 'Start'
|
||||
db.delete_table('workflows_start')
|
||||
|
||||
# Deleting model 'WorkflowNode'
|
||||
db.delete_table('workflows_workflownode')
|
||||
|
||||
# Deleting field 'Workflow.initial_node'
|
||||
db.delete_column('workflows_workflow', 'initial_node_id')
|
||||
|
||||
# User chose to not deal with backwards NULL issues for 'WorkflowInstance.workflow_state'
|
||||
raise RuntimeError("Cannot reverse this migration. 'WorkflowInstance.workflow_state' and its values cannot be restored.")
|
||||
|
||||
# Adding unique constraint on 'WorkflowInstance', fields ['object_id', 'content_type', 'workflow']
|
||||
db.create_unique('workflows_workflowinstance', ['object_id', 'content_type_id', 'workflow_id'])
|
||||
|
||||
|
||||
models = {
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'workflows.ability': {
|
||||
'Meta': {'object_name': 'Ability'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
|
||||
},
|
||||
'workflows.end': {
|
||||
'Meta': {'object_name': 'End'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||
},
|
||||
'workflows.start': {
|
||||
'Meta': {'object_name': 'Start'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True'})
|
||||
},
|
||||
'workflows.state': {
|
||||
'Meta': {'object_name': 'State'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'max_length': '128'})
|
||||
},
|
||||
'workflows.workflow': {
|
||||
'Meta': {'object_name': 'Workflow'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'initial_node': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_initial_node'", 'null': 'True', 'to': "orm['workflows.WorkflowNode']"}),
|
||||
'initial_state': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'workflow_initial_state'", 'null': 'True', 'to': "orm['workflows.WorkflowState']"}),
|
||||
'label': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'})
|
||||
},
|
||||
'workflows.workflowinstance': {
|
||||
'Meta': {'object_name': 'WorkflowInstance'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'workflow_instance_object'", 'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"})
|
||||
},
|
||||
'workflows.workflowinstanceactivenode': {
|
||||
'Meta': {'object_name': 'WorkflowInstanceActiveNode'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'workflow_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.WorkflowInstance']"}),
|
||||
'workflow_node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.WorkflowNode']"})
|
||||
},
|
||||
'workflows.workflowinstanceactivestate': {
|
||||
'Meta': {'unique_together': "(('workflow_instance', 'state'),)", 'object_name': 'WorkflowInstanceActiveState'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']", 'null': 'True'}),
|
||||
'workflow_instance': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.WorkflowInstance']"})
|
||||
},
|
||||
'workflows.workflownode': {
|
||||
'Meta': {'object_name': 'WorkflowNode'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
|
||||
'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"})
|
||||
},
|
||||
'workflows.workflowstate': {
|
||||
'Meta': {'unique_together': "(('workflow', 'state'),)", 'object_name': 'WorkflowState'},
|
||||
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.State']"}),
|
||||
'workflow': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['workflows.Workflow']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['workflows']
|
||||
@@ -4,11 +4,14 @@ from django.db import models
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import ugettext
|
||||
|
||||
from permissions.models import StoredPermission
|
||||
|
||||
from .literals import OPERAND_CHOICES, OPERAND_AND
|
||||
#from .literals import NODE_TYPE_TASK, NODE_TYPE_START, NODE_TYPE_END
|
||||
|
||||
#NODE_TYPE_CHOICES
|
||||
|
||||
class Ability(models.Model):
|
||||
label = models.CharField(max_length=128, unique=True, verbose_name = _(u'label'))
|
||||
@@ -24,44 +27,149 @@ class Ability(models.Model):
|
||||
|
||||
class Workflow(models.Model):
|
||||
label = models.CharField(max_length=128, unique=True, verbose_name = _(u'label'))
|
||||
initial_node = models.ForeignKey('WorkflowNode', related_name='workflow_initial_node', blank=True, null=True, verbose_name=_(u'initial node'))
|
||||
initial_state = models.ForeignKey('WorkflowState', related_name='workflow_initial_state', blank=True, null=True, verbose_name=_(u'initial state'))
|
||||
description = models.TextField(blank=True, verbose_name=_(u'description'))
|
||||
|
||||
def __unicode__(self):
|
||||
return self.label
|
||||
|
||||
@property
|
||||
def workflow_nodes(self):
|
||||
return self.workflownode_set
|
||||
|
||||
def get_nodes(self):
|
||||
return [workflow_node.node for workflow_node in self.workflownode_set.all()]
|
||||
|
||||
def add_node(self, node):
|
||||
workflow_node = WorkflowNode(
|
||||
workflow=self,
|
||||
node=node)
|
||||
workflow_node.save()
|
||||
return workflow_node
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
is_new = not self.pk
|
||||
result = super(Workflow, self).save(*args, **kwargs)
|
||||
|
||||
if is_new:
|
||||
# Instanciate a new start node
|
||||
start_node = Start()
|
||||
start_node.save()
|
||||
|
||||
# Set the start node a
|
||||
workflow_node = self.add_node(node=start_node)
|
||||
|
||||
self.initial_node = workflow_node
|
||||
self.save()
|
||||
|
||||
return result
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'workflow')
|
||||
verbose_name_plural = _(u'workflows')
|
||||
|
||||
|
||||
class State(models.Model):
|
||||
|
||||
|
||||
class Node(models.Model):
|
||||
"""
|
||||
Must provide:
|
||||
possible_next_nodes()
|
||||
Arguments: None
|
||||
Returns:
|
||||
List of possible nodes after this one executes
|
||||
|
||||
choices()
|
||||
Arguments: workflow
|
||||
Returns:
|
||||
{
|
||||
'next_node': workflow.nodes.all()
|
||||
}
|
||||
|
||||
execute()
|
||||
Arguments: workflow_instance
|
||||
Returns: next_node
|
||||
"""
|
||||
|
||||
label = models.CharField(max_length=128, verbose_name=_(u'label'))
|
||||
description = models.TextField(blank=True, verbose_name=_(u'description'))
|
||||
|
||||
def __unicode__(self):
|
||||
#return '%s (%s)' % (self.name, self.workflow.name)
|
||||
return self.label
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'state')
|
||||
verbose_name_plural = _(u'states')
|
||||
abstract = True
|
||||
|
||||
|
||||
class Start(Node):
|
||||
"""
|
||||
The node with which all workflows start
|
||||
"""
|
||||
content_type = models.ForeignKey(ContentType, null=True)
|
||||
object_id = models.PositiveIntegerField(null=True)
|
||||
next_node = generic.GenericForeignKey(ct_field='content_type', fk_field='object_id')
|
||||
|
||||
def __unicode__(self):
|
||||
return ugettext(u'Start')
|
||||
|
||||
def possible_next_nodes(self):
|
||||
return self.next_node
|
||||
|
||||
def choices(self, workflow):
|
||||
return {
|
||||
'next_node': workflow.nodes.all()
|
||||
}
|
||||
|
||||
def execute(self, workflow_instance):
|
||||
return self.next_node
|
||||
|
||||
class Meta(Node.Meta):
|
||||
verbose_name = _(u'start')
|
||||
verbose_name_plural = _(u'starts')
|
||||
|
||||
|
||||
class Transition(models.Model):
|
||||
class End(Node):
|
||||
class Meta(Node.Meta):
|
||||
verbose_name = _(u'start')
|
||||
verbose_name_plural = _(u'starts')
|
||||
|
||||
|
||||
'''
|
||||
class Sequence(Node):
|
||||
"""
|
||||
A node that is enabled after the completion of a preceding node in the same workflow
|
||||
"""
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.PositiveIntegerField()
|
||||
next_node = generic.GenericForeignKey(ct_field='content_type', fk_field='object_id')
|
||||
#node_type = NODE_TYPE_TASK
|
||||
|
||||
def execute(self):
|
||||
return self.next_node
|
||||
|
||||
class Meta(Node.Meta):
|
||||
verbose_name = _(u'task')
|
||||
verbose_name_plural = _(u'tasks')
|
||||
'''
|
||||
|
||||
class State(models.Model):
|
||||
label = models.CharField(max_length=128, verbose_name=_(u'label'))
|
||||
description = models.TextField(blank=True, verbose_name=_(u'description'))
|
||||
|
||||
def __unicode__(self):
|
||||
#return '%s (%s)' % (self.name, self.workflow.name)
|
||||
return self.label
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'transition')
|
||||
verbose_name_plural = _(u'transitions')
|
||||
|
||||
|
||||
verbose_name = _(u'state')
|
||||
verbose_name_plural = _(u'states')
|
||||
ordering = ('label',)
|
||||
|
||||
|
||||
class WorkflowState(models.Model):
|
||||
"""
|
||||
List of possible states the object of this worflow could be in
|
||||
"""
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u'workflow'))
|
||||
state = models.ForeignKey(State, verbose_name=_(u'state'))
|
||||
description = models.TextField(blank=True, verbose_name=_(u'description'))
|
||||
@@ -69,17 +177,33 @@ class WorkflowState(models.Model):
|
||||
def __unicode__(self):
|
||||
return unicode(self.state)
|
||||
|
||||
@property
|
||||
def transitions(self):
|
||||
return self.workflowstatetransition_set
|
||||
|
||||
class Meta:
|
||||
#unique_together = ('workflow', 'state')
|
||||
unique_together = ('workflow', 'state')
|
||||
verbose_name = _(u'workflow state')
|
||||
verbose_name_plural = _(u'workflows states')
|
||||
|
||||
# TODO: Reduntant - remove
|
||||
class WorkflowNode(models.Model):
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u'workflow'))
|
||||
content_type = models.ForeignKey(ContentType)#, limit_choices_to={'model__in': ('model1', 'model2')})#, related_name='workflow_state_ability_object')#, blank=True, null=True)
|
||||
object_id = models.PositiveIntegerField()#blank=True, null=True)
|
||||
node = generic.GenericForeignKey(ct_field='content_type', fk_field='object_id')
|
||||
description = models.TextField(blank=True, verbose_name=_(u'description'))
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.node)
|
||||
|
||||
class WorkflowStateAbilityGrant(models.Model):
|
||||
#def save(self, *args, **kwargs):
|
||||
# if not issubclass(
|
||||
# return super(WorkflowNode, self).save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
#unique_together = ('workflow', 'state')
|
||||
verbose_name = _(u'workflow node')
|
||||
verbose_name_plural = _(u'workflows nodes')
|
||||
|
||||
"""
|
||||
class WorkflowTaskAbilityGrant(models.Model):
|
||||
workflow_state = models.ForeignKey(WorkflowState, related_name='workflow_state_ability', verbose_name=_(u'workflow state'))
|
||||
content_type = models.ForeignKey(ContentType, related_name='workflow_state_ability_object')#, blank=True, null=True)
|
||||
object_id = models.PositiveIntegerField()#blank=True, null=True)
|
||||
@@ -133,16 +257,69 @@ class WorkflowStateTransitionAbility(models.Model):
|
||||
verbose_name = _(u'transition')
|
||||
verbose_name_plural = _(u'transitions')
|
||||
|
||||
|
||||
"""
|
||||
class WorkflowInstance(models.Model):
|
||||
workflow = models.ForeignKey(Workflow, verbose_name = _(u'workflow'))
|
||||
workflow = models.ForeignKey(Workflow, verbose_name=_(u'workflow'))
|
||||
content_type = models.ForeignKey(ContentType, verbose_name=_(u'Content type'), related_name='workflow_instance_object')#, blank=True, null=True)
|
||||
object_id = models.PositiveIntegerField()#blank=True, null=True)
|
||||
content_object = generic.GenericForeignKey(ct_field='content_type', fk_field='object_id')
|
||||
workflow_state = models.ForeignKey(WorkflowState, related_name='workflow_instance_state', verbose_name=_(u'state'))
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.content_object)
|
||||
|
||||
@property
|
||||
def active_nodes(self):
|
||||
return self.workflowinstanceactivenode_set
|
||||
|
||||
def set_active_state(self, state):
|
||||
active_state = self.get_active_state()
|
||||
if active_state:
|
||||
active_state.delete()
|
||||
|
||||
# Trigger an exception if the state argument if not allowed for this workflow
|
||||
state = WorkflowState.objects.get(workflow=self.workflow, state=state).state
|
||||
|
||||
self.workflowinstanceactivestate_set.create(
|
||||
workflow_instance = self,
|
||||
state = state
|
||||
)
|
||||
|
||||
def get_active_state(self):
|
||||
try:
|
||||
return self.workflowinstanceactivestate_set.get().state
|
||||
except WorkflowInstanceActiveState.DoesNotExist:
|
||||
return None
|
||||
|
||||
active_state = property(get_active_state, set_active_state)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('content_type', 'object_id', 'workflow')
|
||||
verbose_name = _(u'workflow instance')
|
||||
verbose_name_plural = _(u'workflow instances')
|
||||
|
||||
# unique_together = ('content_type', 'object_id', 'workflow')
|
||||
|
||||
|
||||
class WorkflowInstanceActiveNode(models.Model):
|
||||
workflow_instance = models.ForeignKey(WorkflowInstance, verbose_name=_(u'workflow instance'))
|
||||
workflow_node = models.ForeignKey(WorkflowNode, verbose_name=_(u'workflow node'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'workflow instance active node')
|
||||
verbose_name_plural = _(u'workflow instances active nodes')
|
||||
|
||||
|
||||
class WorkflowInstanceActiveState(models.Model):
|
||||
"""
|
||||
This class holds the active state for the workflow instance
|
||||
"""
|
||||
workflow_instance = models.ForeignKey(WorkflowInstance, verbose_name=_(u'workflow instance'))
|
||||
state = models.ForeignKey(State, null=True, verbose_name=_(u'state'))
|
||||
|
||||
class Meta:
|
||||
unique_together = ('workflow_instance', 'state')
|
||||
verbose_name = _(u'workflow instance active state')
|
||||
verbose_name_plural = _(u'workflow instances active states')
|
||||
|
||||
|
||||
# TODO: WorkflowInstanceActiveNodeHistory
|
||||
# TODO: WorkflowInstanceActiveStateHistory
|
||||
|
||||
@@ -16,8 +16,8 @@ PERMISSION_STATE_SETUP_CREATE = Permission.objects.register(namespace, 'state_se
|
||||
PERMISSION_STATE_SETUP_EDIT = Permission.objects.register(namespace, 'state_setup_edit', _(u'Edit existing state templates'))
|
||||
PERMISSION_STATE_SETUP_DELETE = Permission.objects.register(namespace, 'state_setup_delete', _(u'Delete existing state templates'))
|
||||
|
||||
PERMISSION_TRANSITION_SETUP_VIEW = Permission.objects.register(namespace, 'transition_setup_view', _(u'View existing transition templates'))
|
||||
PERMISSION_TRANSITION_SETUP_CREATE = Permission.objects.register(namespace, 'transition_setup_create', _(u'Create new transition templates'))
|
||||
PERMISSION_TRANSITION_SETUP_EDIT = Permission.objects.register(namespace, 'transition_setup_edit', _(u'Edit existing transition templates'))
|
||||
PERMISSION_TRANSITION_SETUP_DELETE = Permission.objects.register(namespace, 'transition_setup_delete', _(u'Delete existing transition templates'))
|
||||
#PERMISSION_TRANSITION_SETUP_VIEW = Permission.objects.register(namespace, 'transition_setup_view', _(u'View existing transition templates'))
|
||||
#PERMISSION_TRANSITION_SETUP_CREATE = Permission.objects.register(namespace, 'transition_setup_create', _(u'Create new transition templates'))
|
||||
#PERMISSION_TRANSITION_SETUP_EDIT = Permission.objects.register(namespace, 'transition_setup_edit', _(u'Edit existing transition templates'))
|
||||
#PERMISSION_TRANSITION_SETUP_DELETE = Permission.objects.register(namespace, 'transition_setup_delete', _(u'Delete existing transition templates'))
|
||||
|
||||
|
||||
@@ -11,17 +11,11 @@ urlpatterns = patterns('workflows.views',
|
||||
url(r'^setup/workflow/state/(?P<workflow_state_pk>\d+)/edit/$', 'setup_workflow_state_edit', (), 'setup_workflow_state_edit'),
|
||||
url(r'^setup/workflow/state/(?P<workflow_state_pk>\d+)/remove/$', 'setup_workflow_state_remove', (), 'setup_workflow_state_remove'),
|
||||
|
||||
url(r'^setup/workflow/state/(?P<workflow_state_pk>\d+)/transition/list/$', 'setup_workflow_state_transitions_list', (), 'setup_workflow_state_transitions_list'),
|
||||
url(r'^setup/workflow/state/(?P<workflow_state_pk>\d+)/transition/add/$', 'setup_workflow_state_transition_add', (), 'setup_workflow_state_transition_add'),
|
||||
url(r'^setup/workflow/state/transition/(?P<workflow_state_transition_pk>\d+)/edit/$', 'setup_workflow_state_transition_edit', (), 'setup_workflow_state_transition_edit'),
|
||||
|
||||
url(r'^setup/state/list/$', 'setup_state_list', (), 'setup_state_list'),
|
||||
url(r'^setup/state/create/$', 'setup_state_create', (), 'setup_state_create'),
|
||||
url(r'^setup/state/(?P<state_pk>\d+)/edit/$', 'setup_state_edit', (), 'setup_state_edit'),
|
||||
url(r'^setup/state/(?P<state_pk>\d+)/delete/$', 'setup_state_delete', (), 'setup_state_delete'),
|
||||
|
||||
url(r'^setup/transition/list/$', 'setup_transition_list', (), 'setup_transition_list'),
|
||||
url(r'^setup/transition/create/$', 'setup_transition_create', (), 'setup_transition_create'),
|
||||
url(r'^setup/transition/(?P<transition_pk>\d+)/edit/$', 'setup_transition_edit', (), 'setup_transition_edit'),
|
||||
url(r'^setup/transition/(?P<transition_pk>\d+)/delete/$', 'setup_transition_delete', (), 'setup_transition_delete'),
|
||||
|
||||
url(r'^setup/workflow/(?P<workflow_pk>\d+)/node/list/$', 'setup_workflow_node_list', (), 'setup_workflow_node_list'),
|
||||
url(r'^setup/workflow/node/(?P<workflow_node_pk>\d+)/edit/$', 'setup_workflow_node_edit', (), 'setup_workflow_node_edit'),
|
||||
)
|
||||
|
||||
@@ -18,18 +18,14 @@ from common.utils import encapsulate
|
||||
#from common.widgets import two_state_template
|
||||
#from acls.models import AccessEntry
|
||||
|
||||
from .models import Workflow, State, Transition, WorkflowState
|
||||
from .models import Workflow, State, WorkflowState, WorkflowNode
|
||||
from .forms import (WorkflowSetupForm, StateSetupForm,
|
||||
WorkflowStateSetupForm, TransitionSetupForm,
|
||||
WorkflowStateTransitionSetupForm)
|
||||
WorkflowStateSetupForm, WorkflowNodeSetupForm)
|
||||
from .permissions import (PERMISSION_WORKFLOW_SETUP_VIEW,
|
||||
PERMISSION_WORKFLOW_SETUP_CREATE, PERMISSION_WORKFLOW_SETUP_EDIT,
|
||||
PERMISSION_WORKFLOW_SETUP_DELETE, PERMISSION_STATE_SETUP_VIEW,
|
||||
PERMISSION_STATE_SETUP_CREATE, PERMISSION_STATE_SETUP_EDIT,
|
||||
PERMISSION_STATE_SETUP_DELETE, PERMISSION_TRANSITION_SETUP_VIEW,
|
||||
PERMISSION_TRANSITION_SETUP_CREATE, PERMISSION_TRANSITION_SETUP_EDIT,
|
||||
PERMISSION_TRANSITION_SETUP_DELETE)
|
||||
|
||||
PERMISSION_STATE_SETUP_DELETE)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -207,7 +203,7 @@ def setup_workflow_state_edit(request, workflow_state_pk):
|
||||
form = WorkflowStateSetupForm(workflow=workflow_state.workflow, instance=workflow_state)
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'edit worflow state'),
|
||||
'title': _(u'edit worflow state: %s') % workflow_state,
|
||||
'form': form,
|
||||
'workflow': workflow_state.workflow,
|
||||
'workflow_state': workflow_state,
|
||||
@@ -272,6 +268,54 @@ def setup_workflow_state_remove(request, workflow_state_pk=None, workflow_state_
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
# Nodes
|
||||
def setup_workflow_node_list(request, workflow_pk):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
workflow = get_object_or_404(Workflow, pk=workflow_pk)
|
||||
|
||||
context = {
|
||||
'object_list': workflow.workflow_nodes.all(),
|
||||
'extra_columns': [
|
||||
{'name': _(u'Posible next nodes'), 'attribute': encapsulate(lambda workflow_node: workflow_node.node.possible_next_nodes() or _(u'None'))},
|
||||
],
|
||||
'title': _(u'nodes of workflow: %s') % workflow,
|
||||
'hide_link': True,
|
||||
'workflow': workflow,
|
||||
'navigation_object_list': [
|
||||
{'object': 'workflow', 'name': _(u'workflow')},
|
||||
],
|
||||
'list_object_variable_name': 'workflow_node',
|
||||
}
|
||||
|
||||
return render_to_response('generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def setup_workflow_node_edit(request, workflow_node_pk):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
workflow_node = get_object_or_404(WorkflowNode, pk=workflow_node_pk)
|
||||
redirect_url = reverse('setup_workflow_node_list', args=[workflow_node.workflow.pk])
|
||||
|
||||
if request.method == 'POST':
|
||||
form = WorkflowNodeSetupForm(workflow=workflow_node.workflow, instance=workflow_node, data=request.POST)
|
||||
if form.is_valid():
|
||||
state = form.save()
|
||||
messages.success(request, _(u'worflow node edited succesfully.'))
|
||||
return HttpResponseRedirect(redirect_url)
|
||||
else:
|
||||
form = WorkflowNodeSetupForm(workflow=workflow_node.workflow, instance=workflow_node)
|
||||
|
||||
return render_to_response('generic_form.html', {
|
||||
'title': _(u'edit worflow node: %s') % workflow_node,
|
||||
'form': form,
|
||||
'workflow': workflow_node.workflow,
|
||||
'workflow_node': workflow_node,
|
||||
'navigation_object_list': [
|
||||
{'object': 'workflow', 'name': _(u'workflow')},
|
||||
{'object': 'workflow_node', 'name': _(u'workflow node')}
|
||||
],
|
||||
}, context_instance=RequestContext(request))
|
||||
"""
|
||||
def setup_workflow_transition_list(request, state_workflow_pk):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
workflow = get_object_or_404(Workflow, pk=workflow_pk)
|
||||
@@ -289,6 +333,7 @@ def setup_workflow_transition_list(request, state_workflow_pk):
|
||||
|
||||
return render_to_response('generic_list.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
"""
|
||||
# States
|
||||
def setup_state_list(request):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_STATE_SETUP_VIEW])
|
||||
@@ -395,7 +440,7 @@ def setup_state_delete(request, state_pk=None, state_pk_list=None):
|
||||
return render_to_response('generic_confirm.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
"""
|
||||
# Transitions
|
||||
def setup_transition_list(request):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_TRANSITION_SETUP_VIEW])
|
||||
@@ -507,8 +552,8 @@ def setup_transition_delete(request, transition_pk=None, transition_pk_list=None
|
||||
|
||||
return render_to_response('generic_confirm.html', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
|
||||
"""
|
||||
"""
|
||||
# State transitions
|
||||
def setup_workflow_state_transitions_list(request, workflow_state_pk):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
|
||||
@@ -587,7 +632,7 @@ def setup_workflow_state_transition_edit(request, work_state_transition_pk):
|
||||
],
|
||||
'list_object_variable_name': 'workflow_state_transition',
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
"""
|
||||
"""
|
||||
def setup_state_transition_remove(request, state_transition_pk=None, state_transition_pk_list=None):
|
||||
post_action_redirect = None
|
||||
|
||||
Reference in New Issue
Block a user