Add the workflow state transition list and add views

This commit is contained in:
Roberto Rosario
2012-03-19 01:12:16 -04:00
parent 6cbe1301ca
commit 38426ed32f
5 changed files with 165 additions and 14 deletions

View File

@@ -20,9 +20,12 @@ setup_workflow_create_link = Link(text=_(u'create new workflow'), view='setup_wo
setup_workflow_edit_link = Link(text=_(u'edit'), view='setup_workflow_edit', args='workflow.pk', sprite='chart_organisation', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT]) setup_workflow_edit_link = Link(text=_(u'edit'), view='setup_workflow_edit', args='workflow.pk', sprite='chart_organisation', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_delete_link = Link(text=_(u'delete'), view='setup_workflow_delete', args='workflow.pk', sprite='chart_organisation_delete', permissions=[PERMISSION_WORKFLOW_SETUP_DELETE]) setup_workflow_delete_link = Link(text=_(u'delete'), view='setup_workflow_delete', args='workflow.pk', sprite='chart_organisation_delete', permissions=[PERMISSION_WORKFLOW_SETUP_DELETE])
setup_workflow_states_list_link = Link(text=_(u'states'), view='setup_workflow_states_list', args='workflow.pk', sprite='transmit_go', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT]) setup_workflow_states_list_link = Link(text=_(u'states'), view='setup_workflow_states_list', args='workflow.pk', sprite='transmit_go', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_states_add_link = Link(text=_(u'add state'), view='setup_workflow_state_add', args='workflow.pk', sprite='transmit_add', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT]) setup_workflow_states_add_link = Link(text=_(u'add workflow state'), view='setup_workflow_state_add', args='workflow.pk', sprite='transmit_add', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_states_edit_link = Link(text=_(u'edit state'), view='setup_workflow_state_edit', args='workflow_state.pk', sprite='transmit_edit', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT]) setup_workflow_states_edit_link = Link(text=_(u'edit workflow state'), view='setup_workflow_state_edit', args='workflow_state.pk', sprite='transmit_edit', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_states_remove_link = Link(text=_(u'remove state'), view='setup_workflow_state_remove', args='workflow_state.pk', sprite='transmit_delete', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT]) setup_workflow_states_remove_link = Link(text=_(u'remove workflow state'), view='setup_workflow_state_remove', args='workflow_state.pk', sprite='transmit_delete', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_state_transitions_list_link = Link(text=_(u'workflow state transitions'), view='setup_workflow_state_transitions_list', args='workflow_state.pk', sprite='chart_line', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_workflow_state_transition_add_link = Link(text=_(u'add workflow state transition'), view='setup_workflow_state_transition_add', args='workflow_state.pk', sprite='chart_line_add', permissions=[PERMISSION_WORKFLOW_SETUP_EDIT])
setup_state_list_link = Link(text=_(u'state list'), view='setup_state_list', sprite='transmit', permissions=[PERMISSION_STATE_SETUP_VIEW]) setup_state_list_link = Link(text=_(u'state list'), view='setup_state_list', sprite='transmit', permissions=[PERMISSION_STATE_SETUP_VIEW])
setup_state_create_link = Link(text=_(u'create new state'), view='setup_state_create', sprite='transmit_add', permissions=[PERMISSION_STATE_SETUP_CREATE]) setup_state_create_link = Link(text=_(u'create new state'), view='setup_state_create', sprite='transmit_add', permissions=[PERMISSION_STATE_SETUP_CREATE])
@@ -54,6 +57,7 @@ bind_links([State, 'setup_state_list', 'setup_state_create'], [setup_state_creat
bind_links([Transition], [setup_transition_edit_link, setup_transition_delete_link]) 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_list', 'setup_transition_create'], [setup_transition_create_link], menu_name=u'secondary_menu')
bind_links([WorkflowState], [setup_workflow_states_edit_link, setup_workflow_states_remove_link]) 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')
register_setup(Link(text=_(u'workflows'), view='setup_workflow_list', icon='chart_organisation.png', permissions=[PERMISSION_WORKFLOW_SETUP_VIEW])) register_setup(Link(text=_(u'workflows'), view='setup_workflow_list', icon='chart_organisation.png', permissions=[PERMISSION_WORKFLOW_SETUP_VIEW]))

View File

@@ -3,7 +3,7 @@ from __future__ import absolute_import
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .models import Workflow, State, Transition, WorkflowState from .models import Workflow, State, Transition, WorkflowState, WorkflowStateTransition
class WorkflowSetupForm(forms.ModelForm): class WorkflowSetupForm(forms.ModelForm):
@@ -30,3 +30,16 @@ class WorkflowStateSetupForm(forms.ModelForm):
class TransitionSetupForm(forms.ModelForm): class TransitionSetupForm(forms.ModelForm):
class Meta: class Meta:
model = Transition 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

View File

@@ -70,6 +70,10 @@ class WorkflowState(models.Model):
#return '%s (%s)' % (self.label, self.workflow.label) #return '%s (%s)' % (self.label, self.workflow.label)
return unicode(self.state) return unicode(self.state)
@property
def transitions(self):
return self.workflowstatetransition_set
class Meta: class Meta:
verbose_name = _(u'workflow state') verbose_name = _(u'workflow state')
verbose_name_plural = _(u'workflows states') verbose_name_plural = _(u'workflows states')
@@ -102,7 +106,7 @@ class WorkflowStateAbilityGrant(models.Model):
class WorkflowStateTransition(models.Model): class WorkflowStateTransition(models.Model):
workflow_state_source = models.ForeignKey(WorkflowState, related_name='workflow_state_transition_source', verbose_name=_(u'workflow state source')) workflow_state_source = models.ForeignKey(WorkflowState, verbose_name=_(u'workflow state source'))
transition = models.ForeignKey(Transition, related_name='workflow_state_transition', verbose_name=_(u'transition')) transition = models.ForeignKey(Transition, related_name='workflow_state_transition', verbose_name=_(u'transition'))
workflow_state_destination = models.ForeignKey(WorkflowState, related_name='workflow_state_transition_destination', verbose_name=_(u'workflow state destination')) workflow_state_destination = models.ForeignKey(WorkflowState, related_name='workflow_state_transition_destination', verbose_name=_(u'workflow state destination'))
description = models.TextField(blank=True, verbose_name=_(u'description')) description = models.TextField(blank=True, verbose_name=_(u'description'))

View File

@@ -5,11 +5,15 @@ urlpatterns = patterns('workflows.views',
url(r'^setup/workflow/create/$', 'setup_workflow_create', (), 'setup_workflow_create'), url(r'^setup/workflow/create/$', 'setup_workflow_create', (), 'setup_workflow_create'),
url(r'^setup/workflow/(?P<workflow_pk>\d+)/edit/$', 'setup_workflow_edit', (), 'setup_workflow_edit'), url(r'^setup/workflow/(?P<workflow_pk>\d+)/edit/$', 'setup_workflow_edit', (), 'setup_workflow_edit'),
url(r'^setup/workflow/(?P<workflow_pk>\d+)/delete/$', 'setup_workflow_delete', (), 'setup_workflow_delete'), url(r'^setup/workflow/(?P<workflow_pk>\d+)/delete/$', 'setup_workflow_delete', (), 'setup_workflow_delete'),
url(r'^setup/workflow/(?P<workflow_pk>\d+)/state/list/$', 'setup_workflow_states_list', (), 'setup_workflow_states_list'), url(r'^setup/workflow/(?P<workflow_pk>\d+)/state/list/$', 'setup_workflow_states_list', (), 'setup_workflow_states_list'),
url(r'^setup/workflow/(?P<workflow_pk>\d+)/state/create/$', 'setup_workflow_state_add', (), 'setup_workflow_state_add'), url(r'^setup/workflow/(?P<workflow_pk>\d+)/state/add/$', 'setup_workflow_state_add', (), 'setup_workflow_state_add'),
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+)/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+)/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/state/list/$', 'setup_state_list', (), 'setup_state_list'), 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/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+)/edit/$', 'setup_state_edit', (), 'setup_state_edit'),
@@ -19,5 +23,4 @@ urlpatterns = patterns('workflows.views',
url(r'^setup/transition/create/$', 'setup_transition_create', (), 'setup_transition_create'), 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+)/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/transition/(?P<transition_pk>\d+)/delete/$', 'setup_transition_delete', (), 'setup_transition_delete'),
) )

View File

@@ -20,7 +20,8 @@ from common.utils import encapsulate
from .models import Workflow, State, Transition, WorkflowState from .models import Workflow, State, Transition, WorkflowState
from .forms import (WorkflowSetupForm, StateSetupForm, from .forms import (WorkflowSetupForm, StateSetupForm,
WorkflowStateSetupForm, TransitionSetupForm) WorkflowStateSetupForm, TransitionSetupForm,
WorkflowStateTransitionSetupForm)
from .permissions import (PERMISSION_WORKFLOW_SETUP_VIEW, from .permissions import (PERMISSION_WORKFLOW_SETUP_VIEW,
PERMISSION_WORKFLOW_SETUP_CREATE, PERMISSION_WORKFLOW_SETUP_EDIT, PERMISSION_WORKFLOW_SETUP_CREATE, PERMISSION_WORKFLOW_SETUP_EDIT,
PERMISSION_WORKFLOW_SETUP_DELETE, PERMISSION_STATE_SETUP_VIEW, PERMISSION_WORKFLOW_SETUP_DELETE, PERMISSION_STATE_SETUP_VIEW,
@@ -230,9 +231,9 @@ def setup_workflow_state_remove(request, workflow_state_pk=None, workflow_state_
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
try: try:
Permission.objects.check_permissions(request.user, [PERMISSION_STATE_SETUP_DELETE]) Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
except PermissionDenied: except PermissionDenied:
workflow_states = AccessEntry.objects.filter_objects_by_access(PERMISSION_STATE_SETUP_DELETE, request.user, workflow_states) workflow_states = AccessEntry.objects.filter_objects_by_access(PERMISSION_WORKFLOW_SETUP_EDIT, request.user, workflow_states)
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/'))) next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
@@ -403,9 +404,6 @@ def setup_transition_list(request):
'object_list': Transition.objects.all(), 'object_list': Transition.objects.all(),
'title': _(u'transitions'), 'title': _(u'transitions'),
'hide_link': True, 'hide_link': True,
#'extra_columns': [
# {'name': _(u'Initial state'), 'attribute': encapsulate(lambda transition: transition.initial_state or _(u'None'))},
#],
'list_object_variable_name': 'transition', 'list_object_variable_name': 'transition',
} }
@@ -509,3 +507,132 @@ def setup_transition_delete(request, transition_pk=None, transition_pk_list=None
return render_to_response('generic_confirm.html', context, return render_to_response('generic_confirm.html', context,
context_instance=RequestContext(request)) 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])
workflow_state = get_object_or_404(WorkflowState, pk=workflow_state_pk)
context = {
'object_list': workflow_state.transitions.all(),
'title': _(u'transitions for workflow state: %s') % workflow_state,
'hide_link': True,
'workflow_state': workflow_state,
'workflow': workflow_state.workflow,
'navigation_object_list': [
{'object': 'workflow', 'name': _(u'workflow')},
{'object': 'workflow_state', 'name': _(u'state')},
],
'list_object_variable_name': 'state_transition',
}
return render_to_response('generic_list.html', context,
context_instance=RequestContext(request))
def setup_workflow_state_transition_add(request, workflow_state_pk):
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
workflow_state = get_object_or_404(WorkflowState, pk=workflow_state_pk)
redirect_url = reverse('setup_workflow_state_transitions_list', args=[workflow_state_pk])
if request.method == 'POST':
form = WorkflowStateTransitionSetupForm(workflow_state=workflow_state, data=request.POST)
if form.is_valid():
workflow_state_transition = form.save()
messages.success(request, _(u'worflow state transition created succesfully.'))
return HttpResponseRedirect(redirect_url)
else:
form = WorkflowStateTransitionSetupForm(workflow_state=workflow_state)
return render_to_response('generic_form.html', {
'title': _(u'add transition to worflow state: %s') % workflow_state,
'form': form,
'workflow_state': workflow_state,
'workflow': workflow_state.workflow,
'navigation_object_list': [
{'object': 'workflow', 'name': _(u'workflow')},
{'object': 'workflow_state', 'name': _(u'state')},
],
}, context_instance=RequestContext(request))
"""
def setup_state_transition_edit(request, state_transition_pk):
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_SETUP_EDIT])
state_transition = get_object_or_404(WorkflowState, pk=state_transition_pk)
redirect_url = reverse('setup_state_transitions_list', args=[state_transition.state.pk])
if request.method == 'POST':
form = WorkflowStateSetupForm(state=state_transition.state, instance=state_transition, data=request.POST)
if form.is_valid():
state = form.save()
messages.success(request, _(u'worflow state edited succesfully.'))
return HttpResponseRedirect(redirect_url)
else:
form = WorkflowStateSetupForm(state=state_transition.state, instance=state_transition)
return render_to_response('generic_form.html', {
'title': _(u'edit worflow state'),
'form': form,
'state': state_transition.state,
'state_transition': state_transition,
'navigation_object_list': [
{'object': 'state', 'name': _(u'state')},
{'object': 'state_transition', 'name': _(u'state state')}
],
}, context_instance=RequestContext(request))
def setup_state_transition_remove(request, state_transition_pk=None, state_transition_pk_list=None):
post_action_redirect = None
if state_transition_pk:
state_transitions = [get_object_or_404(WorkflowState, pk=state_transition_pk)]
post_action_redirect = reverse('setup_state_transitions_list', args=[state_transitions[0].state.pk])
elif state_transition_pk_list:
state_transitions = [get_object_or_404(WorkflowState, pk=state_transition_pk) for state_transition_pk in state_transition_pk_list.split(',')]
else:
messages.error(request, _(u'Must provide at least one state state.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
try:
Permission.objects.check_permissions(request.user, [PERMISSION_STATE_SETUP_DELETE])
except PermissionDenied:
state_transitions = AccessEntry.objects.filter_objects_by_access(PERMISSION_STATE_SETUP_DELETE, request.user, state_transitions)
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
if request.method == 'POST':
for state_transition in state_transitions:
try:
state_transition.delete()
messages.success(request, _(u'Workflow states "%s" removed successfully.') % state_transition)
except Exception, e:
messages.error(request, _(u'Error removing state state "%(state_transition)s": %(error)s') % {
'state_transition': state_transition, 'error': e
})
return HttpResponseRedirect(next)
context = {
'object_name': _(u'state state'),
'delete_view': True,
'previous': previous,
'next': next,
'form_icon': u'transmit_delete.png',
'state': state_transitions[0].state,
'navigation_object_list': [
{'object': 'state', 'name': _(u'state')},
{'object': 'state_transition', 'name': _(u'state state')}
],
}
if len(state_transitions) == 1:
context['title'] = _(u'Are you sure you wish to remove the state state: %s?') % ', '.join([unicode(d) for d in state_transitions])
context['state_transition'] = state_transitions[0]
elif len(states) > 1:
context['title'] = _(u'Are you sure you wish to remove the state states: %s?') % ', '.join([unicode(d) for d in state_transitions])
return render_to_response('generic_confirm.html', context,
context_instance=RequestContext(request))
"""