diff --git a/mayan/apps/document_states/api_views.py b/mayan/apps/document_states/api_views.py index 5f998db115..90df8863cb 100644 --- a/mayan/apps/document_states/api_views.py +++ b/mayan/apps/document_states/api_views.py @@ -31,7 +31,7 @@ from .storages import storage_workflowimagecache from .tasks import task_generate_workflow_image -class APIDocumentTypeWorkflowListView(generics.ListAPIView): +class APIDocumentTypeWorkflowRuntimeProxyListView(generics.ListAPIView): """ get: Returns a list of all the document type workflows. """ @@ -214,7 +214,7 @@ class APIWorkflowImageView(generics.RetrieveAPIView): return response -class APIWorkflowListView(generics.ListCreateAPIView): +class APIWorkflowRuntimeProxyListView(generics.ListCreateAPIView): """ get: Returns a list of all the workflows. post: Create a new workflow. @@ -229,7 +229,7 @@ class APIWorkflowListView(generics.ListCreateAPIView): if not self.request: return None - return super(APIWorkflowListView, self).get_serializer(*args, **kwargs) + return super(APIWorkflowRuntimeProxyListView, self).get_serializer(*args, **kwargs) def get_serializer_class(self): if self.request.method == 'GET': diff --git a/mayan/apps/document_states/apps.py b/mayan/apps/document_states/apps.py index 0e35c0d59c..065105db19 100644 --- a/mayan/apps/document_states/apps.py +++ b/mayan/apps/document_states/apps.py @@ -29,27 +29,27 @@ from .handlers import ( ) from .html_widgets import WorkflowLogExtraDataWidget, widget_transition_events from .links import ( - link_document_workflow_instance_list, link_setup_document_type_workflows, - link_setup_workflow_document_types, link_setup_workflow_create, - link_setup_workflow_delete, link_setup_workflow_edit, - link_setup_workflow_list, link_setup_workflow_states, - link_setup_workflow_state_action_delete, - link_setup_workflow_state_action_edit, - link_setup_workflow_state_action_list, - link_setup_workflow_state_action_selection, - link_setup_workflow_state_create, link_setup_workflow_state_delete, - link_setup_workflow_state_edit, link_setup_workflow_transitions, - link_setup_workflow_transition_create, - link_setup_workflow_transition_delete, link_setup_workflow_transition_edit, - link_setup_workflow_transition_field_create, - link_setup_workflow_transition_field_delete, - link_setup_workflow_transition_field_edit, - link_setup_workflow_transition_field_list, - link_tool_launch_all_workflows, link_workflow_instance_detail, + link_workflow_instance_list, link_document_type_workflow_templates, + link_workflow_template_document_types, link_workflow_template_create, + link_workflow_template_delete, link_workflow_template_edit, + link_workflow_template_list, link_workflow_template_state_list, + link_workflow_template_state_action_delete, + link_workflow_template_state_action_edit, + link_workflow_template_state_action_list, + link_workflow_template_state_action_selection, + link_workflow_template_state_create, link_workflow_template_state_delete, + link_workflow_template_state_edit, link_workflow_template_transition_list, + link_workflow_template_transition_create, + link_workflow_template_transition_delete, link_workflow_template_transition_edit, + link_workflow_template_transition_field_create, + link_workflow_template_transition_field_delete, + link_workflow_template_transition_field_edit, + link_workflow_template_transition_field_list, + link_tool_launch_workflows, link_workflow_instance_detail, link_workflow_instance_transition, link_workflow_runtime_proxy_document_list, - link_workflow_runtime_proxy_list, link_workflow_preview, + link_workflow_runtime_proxy_list, link_workflow_template_preview, link_workflow_runtime_proxy_state_document_list, link_workflow_runtime_proxy_state_list, - link_workflow_transition_events + link_workflow_template_transition_events ) from .permissions import ( permission_workflow_delete, permission_workflow_edit, @@ -316,49 +316,49 @@ class DocumentStatesApp(MayanAppConfig): ) menu_facet.bind_links( - links=(link_document_workflow_instance_list,), sources=(Document,) + links=(link_workflow_instance_list,), sources=(Document,) ) menu_list_facet.bind_links( links=( link_acl_list, link_events_for_object, link_object_event_types_user_subcriptions_list, - link_setup_workflow_document_types, - link_setup_workflow_states, link_setup_workflow_transitions, - link_workflow_preview + link_workflow_template_document_types, + link_workflow_template_state_list, link_workflow_template_transition_list, + link_workflow_template_preview ), sources=(Workflow,) ) menu_list_facet.bind_links( links=( - link_setup_document_type_workflows, + link_document_type_workflow_templates, ), sources=(DocumentType,) ) menu_main.bind_links(links=(link_workflow_runtime_proxy_list,), position=10) menu_object.bind_links( links=( - link_setup_workflow_delete, link_setup_workflow_edit + link_workflow_template_delete, link_workflow_template_edit ), sources=(Workflow,) ) menu_object.bind_links( links=( - link_setup_workflow_state_edit, - link_setup_workflow_state_action_list, - link_setup_workflow_state_delete + link_workflow_template_state_edit, + link_workflow_template_state_action_list, + link_workflow_template_state_delete ), sources=(WorkflowState,) ) menu_object.bind_links( links=( - link_setup_workflow_transition_edit, - link_workflow_transition_events, - link_setup_workflow_transition_field_list, link_acl_list, - link_setup_workflow_transition_delete + link_workflow_template_transition_edit, + link_workflow_template_transition_events, + link_workflow_template_transition_field_list, link_acl_list, + link_workflow_template_transition_delete ), sources=(WorkflowTransition,) ) menu_object.bind_links( links=( - link_setup_workflow_transition_field_delete, - link_setup_workflow_transition_field_edit + link_workflow_template_transition_field_delete, + link_workflow_template_transition_field_edit ), sources=(WorkflowTransitionField,) ) menu_object.bind_links( @@ -381,21 +381,21 @@ class DocumentStatesApp(MayanAppConfig): ) menu_object.bind_links( links=( - link_setup_workflow_state_action_edit, + link_workflow_template_state_action_edit, link_object_error_list, - link_setup_workflow_state_action_delete, + link_workflow_template_state_action_delete, ), sources=(WorkflowStateAction,) ) menu_secondary.bind_links( - links=(link_setup_workflow_list, link_setup_workflow_create), + links=(link_workflow_template_list, link_workflow_template_create), sources=( - Workflow, 'document_states:setup_workflow_create', - 'document_states:setup_workflow_list' + Workflow, 'document_states:workflow_template_create', + 'document_states:workflow_template_list' ) ) menu_secondary.bind_links( - links=(link_setup_workflow_transition_field_create,), + links=(link_workflow_template_transition_field_create,), sources=( WorkflowTransition, ) @@ -407,31 +407,31 @@ class DocumentStatesApp(MayanAppConfig): ) ) menu_secondary.bind_links( - links=(link_setup_workflow_state_action_selection,), + links=(link_workflow_template_state_action_selection,), sources=( WorkflowState, ) ) menu_secondary.bind_links( links=( - link_setup_workflow_transition_create, + link_workflow_template_transition_create, ), sources=( WorkflowTransition, - 'document_states:setup_workflow_transition_list', + 'document_states:workflow_template_transition_list', ) ) menu_secondary.bind_links( links=( - link_setup_workflow_state_create, + link_workflow_template_state_create, ), sources=( WorkflowState, - 'document_states:setup_workflow_state_list', + 'document_states:workflow_template_state_list', ) ) - menu_setup.bind_links(links=(link_setup_workflow_list,)) + menu_setup.bind_links(links=(link_workflow_template_list,)) - menu_tools.bind_links(links=(link_tool_launch_all_workflows,)) + menu_tools.bind_links(links=(link_tool_launch_workflows,)) post_save.connect( dispatch_uid='workflows_handler_launch_workflow', diff --git a/mayan/apps/document_states/icons.py b/mayan/apps/document_states/icons.py index 9fa519fac1..3115901935 100644 --- a/mayan/apps/document_states/icons.py +++ b/mayan/apps/document_states/icons.py @@ -1,45 +1,44 @@ from __future__ import absolute_import, unicode_literals from mayan.apps.appearance.classes import Icon -from mayan.apps.documents.icons import icon_document_type +from mayan.apps.documents.icons import icon_document, icon_document_type icon_workflow = Icon(driver_name='fontawesome', symbol='sitemap') -icon_document_type_workflow_list = icon_workflow +icon_tool_launch_workflows = icon_workflow -icon_document_workflow_instance_list = Icon( - driver_name='fontawesome', symbol='sitemap' -) -icon_setup_workflow_list = Icon(driver_name='fontawesome', symbol='sitemap') -icon_tool_launch_all_workflows = Icon( - driver_name='fontawesome', symbol='sitemap' -) -icon_workflow_create = Icon( +icon_document_type_workflow_list = icon_workflow +icon_workflow_template_create = Icon( driver_name='fontawesome-dual', primary_symbol='sitemap', secondary_symbol='plus' ) -icon_workflow_delete = Icon(driver_name='fontawesome', symbol='times') -icon_workflow_document_type_list = icon_document_type -icon_workflow_edit = Icon(driver_name='fontawesome', symbol='pencil-alt') -icon_workflow_list = Icon(driver_name='fontawesome', symbol='sitemap') -icon_workflow_preview = Icon(driver_name='fontawesome', symbol='eye') - -icon_workflow_instance_detail = Icon( - driver_name='fontawesome', symbol='sitemap' +icon_workflow_template_delete = Icon(driver_name='fontawesome', symbol='times') +icon_workflow_template_document_type_list = icon_document_type +icon_workflow_template_edit = Icon( + driver_name='fontawesome', symbol='pencil-alt' ) +icon_workflow_template_list = icon_workflow +icon_workflow_template_preview = Icon(driver_name='fontawesome', symbol='eye') + +# Workflow instances + +icon_workflow_instance_detail = icon_workflow +icon_workflow_instance_list = icon_workflow icon_workflow_instance_transition = Icon( driver_name='fontawesome', symbol='arrows-alt-h' ) -icon_workflow_runtime_proxy_document_list = icon_document_type -icon_workflow_runtime_proxy_list = Icon( - driver_name='fontawesome', symbol='sitemap' -) -icon_workflow_runtime_proxy_state_document_list = icon_document_type +# Workflow runtime proxies + +icon_workflow_runtime_proxy_document_list = icon_document +icon_workflow_runtime_proxy_list = icon_workflow +icon_workflow_runtime_proxy_state_document_list = icon_document icon_workflow_runtime_proxy_state_list = Icon( driver_name='fontawesome', symbol='circle' ) +# Workflow transition states + icon_workflow_state_action_delete = Icon( driver_name='fontawesome', symbol='times' ) @@ -57,6 +56,8 @@ icon_workflow_state_create = Icon( icon_workflow_state_delete = Icon(driver_name='fontawesome', symbol='times') icon_workflow_state_edit = Icon(driver_name='fontawesome', symbol='pencil-alt') +# Workflow transition state actions + icon_workflow_state_action = Icon(driver_name='fontawesome', symbol='code') icon_workflow_state_action_delete = Icon( driver_name='fontawesome', symbol='times' @@ -71,6 +72,9 @@ icon_workflow_state_action_selection = Icon( icon_workflow_state_action_list = Icon( driver_name='fontawesome', symbol='code' ) + +# Workflow transitions + icon_workflow_transition = Icon( driver_name='fontawesome', symbol='arrows-alt-h' ) @@ -85,7 +89,11 @@ icon_workflow_transition_edit = Icon( driver_name='fontawesome', symbol='pencil-alt' ) -icon_workflow_transition_field = Icon(driver_name='fontawesome', symbol='table') +# Workflow transition fields + +icon_workflow_transition_field = Icon( + driver_name='fontawesome', symbol='table' +) icon_workflow_transition_field_delete = Icon( driver_name='fontawesome', symbol='times' ) @@ -99,7 +107,6 @@ icon_workflow_transition_field_create = Icon( icon_workflow_transition_field_list = Icon( driver_name='fontawesome', symbol='table' ) - icon_workflow_transition_triggers = Icon( driver_name='fontawesome', symbol='bolt' ) diff --git a/mayan/apps/document_states/links.py b/mayan/apps/document_states/links.py index 1404ff2644..08e8d001cd 100644 --- a/mayan/apps/document_states/links.py +++ b/mayan/apps/document_states/links.py @@ -11,179 +11,185 @@ from .permissions import ( permission_workflow_view, ) -link_setup_document_type_workflows = Link( +# Workflow templates + +link_document_type_workflow_templates = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_document_type_workflow_list', permissions=(permission_document_type_edit,), text=_('Workflows'), - view='document_states:document_type_workflows', + view='document_states:document_type_workflow_templates', ) -link_setup_workflow_create = Link( - icon_class_path='mayan.apps.document_states.icons.icon_workflow_create', +link_workflow_template_create = Link( + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_create', permissions=(permission_workflow_create,), - text=_('Create workflow'), view='document_states:setup_workflow_create' + text=_('Create workflow'), view='document_states:workflow_template_create' ) -link_setup_workflow_delete = Link( +link_workflow_template_delete = Link( args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_workflow_delete', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_delete', permissions=(permission_workflow_delete,), tags='dangerous', text=_('Delete'), - view='document_states:setup_workflow_delete', + view='document_states:workflow_template_delete', ) -link_setup_workflow_document_types = Link( +link_workflow_template_document_types = Link( args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_workflow_document_type_list', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_document_type_list', permissions=(permission_workflow_edit,), text=_('Document types'), - view='document_states:setup_workflow_document_types', + view='document_states:workflow_template_document_types', ) -link_setup_workflow_edit = Link( +link_workflow_template_edit = Link( args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_workflow_edit', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_edit', permissions=(permission_workflow_edit,), - text=_('Edit'), view='document_states:setup_workflow_edit', + text=_('Edit'), view='document_states:workflow_template_edit', ) -link_setup_workflow_list = Link( - icon_class_path='mayan.apps.document_states.icons.icon_setup_workflow_list', +link_workflow_template_list = Link( + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_list', permissions=(permission_workflow_view,), text=_('Workflows'), - view='document_states:setup_workflow_list' + view='document_states:workflow_template_list' ) -link_setup_workflow_state_action_delete = Link( +link_workflow_template_preview = Link( + args='resolved_object.pk', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_template_preview', + permissions=(permission_workflow_view,), + text=_('Preview'), view='document_states:workflow_template_preview' +) + +# Workflow template state actions + +link_workflow_template_state_action_delete = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_action_delete', permissions=(permission_workflow_edit,), tags='dangerous', text=_('Delete'), - view='document_states:setup_workflow_state_action_delete', + view='document_states:workflow_template_state_action_delete', ) -link_setup_workflow_state_action_edit = Link( +link_workflow_template_state_action_edit = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_action_edit', permissions=(permission_workflow_edit,), - text=_('Edit'), view='document_states:setup_workflow_state_action_edit', + text=_('Edit'), view='document_states:workflow_template_state_action_edit', ) -link_setup_workflow_state_action_list = Link( +link_workflow_template_state_action_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_action_list', permissions=(permission_workflow_edit,), text=_('Actions'), - view='document_states:setup_workflow_state_action_list', + view='document_states:workflow_template_state_action_list', ) -link_setup_workflow_state_action_selection = Link( +link_workflow_template_state_action_selection = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_action', permissions=(permission_workflow_edit,), text=_('Create action'), - view='document_states:setup_workflow_state_action_selection', + view='document_states:workflow_template_state_action_selection', ) -link_setup_workflow_state_create = Link( + +# Workflow template states + +link_workflow_template_state_create = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_create', permissions=(permission_workflow_edit,), text=_('Create state'), - view='document_states:setup_workflow_state_create', + view='document_states:workflow_template_state_create', ) -link_setup_workflow_state_delete = Link( +link_workflow_template_state_delete = Link( args='object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_delete', permissions=(permission_workflow_edit,), tags='dangerous', text=_('Delete'), - view='document_states:setup_workflow_state_delete', + view='document_states:workflow_template_state_delete', ) -link_setup_workflow_state_edit = Link( +link_workflow_template_state_edit = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_edit', permissions=(permission_workflow_edit,), - text=_('Edit'), view='document_states:setup_workflow_state_edit', + text=_('Edit'), view='document_states:workflow_template_state_edit', ) -link_setup_workflow_states = Link( +link_workflow_template_state_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_state', permissions=(permission_workflow_view,), text=_('States'), - view='document_states:setup_workflow_state_list', + view='document_states:workflow_template_state_list', ) -link_setup_workflow_transition_create = Link( + +# Workflow template transitions + +link_workflow_template_transition_create = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_create', permissions=(permission_workflow_edit,), text=_('Create transition'), - view='document_states:setup_workflow_transition_create', + view='document_states:workflow_template_transition_create', ) -link_setup_workflow_transition_delete = Link( +link_workflow_template_transition_delete = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_delete', permissions=(permission_workflow_edit,), tags='dangerous', text=_('Delete'), - view='document_states:setup_workflow_transition_delete', + view='document_states:workflow_template_transition_delete', ) -link_setup_workflow_transition_edit = Link( +link_workflow_template_transition_edit = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_edit', permissions=(permission_workflow_edit,), - text=_('Edit'), view='document_states:setup_workflow_transition_edit', + text=_('Edit'), view='document_states:workflow_template_transition_edit', ) -link_setup_workflow_transitions = Link( - args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition', - permissions=(permission_workflow_view,), text=_('Transitions'), - view='document_states:setup_workflow_transition_list', -) -link_workflow_transition_events = Link( +link_workflow_template_transition_events = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_triggers', permissions=(permission_workflow_edit,), text=_('Transition triggers'), - view='document_states:setup_workflow_transition_events' + view='document_states:workflow_template_transition_events' +) +link_workflow_template_transition_list = Link( + args='resolved_object.pk', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition', + permissions=(permission_workflow_view,), text=_('Transitions'), + view='document_states:workflow_template_transition_list', ) # Workflow transition fields -link_setup_workflow_transition_field_create = Link( + +link_workflow_template_transition_field_create = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_field', permissions=(permission_workflow_edit,), text=_('Create field'), - view='document_states:setup_workflow_transition_field_create', + view='document_states:workflow_template_transition_field_create', ) -link_setup_workflow_transition_field_delete = Link( +link_workflow_template_transition_field_delete = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_field_delete', permissions=(permission_workflow_edit,), tags='dangerous', text=_('Delete'), - view='document_states:setup_workflow_transition_field_delete', + view='document_states:workflow_template_transition_field_delete', ) -link_setup_workflow_transition_field_edit = Link( +link_workflow_template_transition_field_edit = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_field_edit', permissions=(permission_workflow_edit,), - text=_('Edit'), view='document_states:setup_workflow_transition_field_edit', + text=_('Edit'), view='document_states:workflow_template_transition_field_edit', ) -link_setup_workflow_transition_field_list = Link( +link_workflow_template_transition_field_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_field_list', permissions=(permission_workflow_edit,), text=_('Fields'), - view='document_states:setup_workflow_transition_field_list', -) - -link_workflow_preview = Link( - args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_workflow_preview', - permissions=(permission_workflow_view,), - text=_('Preview'), view='document_states:workflow_preview' -) -link_tool_launch_all_workflows = Link( - icon_class_path='mayan.apps.document_states.icons.icon_tool_launch_all_workflows', - permissions=(permission_workflow_tools,), - text=_('Launch all workflows'), - view='document_states:tool_launch_all_workflows' + view='document_states:workflow_template_transition_field_list', ) # Document workflow instances -link_document_workflow_instance_list = Link( - args='resolved_object.pk', - icon_class_path='mayan.apps.document_states.icons.icon_document_workflow_instance_list', - permissions=(permission_workflow_view,), text=_('Workflows'), - view='document_states:document_workflow_instance_list', -) + link_workflow_instance_detail = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_instance_detail', permissions=(permission_workflow_view,), text=_('Detail'), view='document_states:workflow_instance_detail', ) +link_workflow_instance_list = Link( + args='resolved_object.pk', + icon_class_path='mayan.apps.document_states.icons.icon_workflow_instance_list', + permissions=(permission_workflow_view,), text=_('Workflows'), + view='document_states:workflow_instance_list', +) link_workflow_instance_transition = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_instance_transition', @@ -192,28 +198,38 @@ link_workflow_instance_transition = Link( ) # Runtime proxies + link_workflow_runtime_proxy_document_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_runtime_proxy_document_list', permissions=(permission_workflow_view,), text=_('Workflow documents'), - view='document_states:workflow_document_list', + view='document_states:workflow_runtime_proxy_document_list', ) link_workflow_runtime_proxy_list = Link( icon_class_path='mayan.apps.document_states.icons.icon_workflow_runtime_proxy_list', permissions=(permission_workflow_view,), - text=_('Workflows'), view='document_states:workflow_list' + text=_('Workflows'), view='document_states:workflow_runtime_proxy_list' ) link_workflow_runtime_proxy_state_document_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_runtime_proxy_state_document_list', permissions=(permission_workflow_view,), text=_('State documents'), - view='document_states:workflow_state_document_list', + view='document_states:workflow_runtime_proxy_state_document_list', ) link_workflow_runtime_proxy_state_list = Link( args='resolved_object.pk', icon_class_path='mayan.apps.document_states.icons.icon_workflow_runtime_proxy_state_list', permissions=(permission_workflow_view,), - text=_('States'), view='document_states:workflow_state_list', + text=_('States'), view='document_states:workflow_runtime_proxy_state_list', +) + +# Tools + +link_tool_launch_workflows = Link( + icon_class_path='mayan.apps.document_states.icons.icon_tool_launch_workflows', + permissions=(permission_workflow_tools,), + text=_('Launch all workflows'), + view='document_states:tool_launch_workflows' ) diff --git a/mayan/apps/document_states/tests/mixins.py b/mayan/apps/document_states/tests/mixins.py index f8ea985a1c..ff09844425 100644 --- a/mayan/apps/document_states/tests/mixins.py +++ b/mayan/apps/document_states/tests/mixins.py @@ -38,19 +38,19 @@ class WorkflowStateViewTestMixin(object): data.update(extra_data) return self.post( - viewname='document_states:setup_workflow_state_create', + viewname='document_states:workflow_template_state_create', kwargs={'pk': self.test_workflow.pk}, data=data ) def _request_test_workflow_state_delete_view(self): return self.post( - viewname='document_states:setup_workflow_state_delete', + viewname='document_states:workflow_template_state_delete', kwargs={'pk': self.test_workflow_state_1.pk} ) def _request_test_workflow_state_edit_view(self): return self.post( - viewname='document_states:setup_workflow_state_edit', + viewname='document_states:workflow_template_state_edit', kwargs={'pk': self.test_workflow_state_1.pk}, data={ 'label': TEST_WORKFLOW_STATE_LABEL_EDITED } @@ -58,7 +58,7 @@ class WorkflowStateViewTestMixin(object): def _request_test_workflow_state_list_view(self): return self.get( - viewname='document_states:setup_workflow_state_list', + viewname='document_states:workflow_template_state_list', kwargs={'pk': self.test_workflow.pk} ) @@ -120,7 +120,7 @@ class WorkflowTestMixin(object): class WorkflowTransitionViewTestMixin(object): def _request_test_workflow_transition_create_view(self): return self.post( - viewname='document_states:setup_workflow_transition_create', + viewname='document_states:workflow_template_transition_create', kwargs={'pk': self.test_workflow.pk}, data={ 'label': TEST_WORKFLOW_TRANSITION_LABEL, 'origin_state': self.test_workflow_state_1.pk, @@ -130,13 +130,13 @@ class WorkflowTransitionViewTestMixin(object): def _request_test_workflow_transition_delete_view(self): return self.post( - viewname='document_states:setup_workflow_transition_delete', + viewname='document_states:workflow_template_transition_delete', kwargs={'pk': self.test_workflow_transition.pk} ) def _request_test_workflow_transition_edit_view(self): return self.post( - viewname='document_states:setup_workflow_transition_edit', + viewname='document_states:workflow_template_transition_edit', kwargs={'pk': self.test_workflow_transition.pk}, data={ 'label': TEST_WORKFLOW_TRANSITION_LABEL_EDITED, 'origin_state': self.test_workflow_state_1.pk, @@ -146,7 +146,7 @@ class WorkflowTransitionViewTestMixin(object): def _request_test_workflow_transition_list_view(self): return self.get( - viewname='document_states:setup_workflow_transition_list', + viewname='document_states:workflow_template_transition_list', kwargs={'pk': self.test_workflow.pk} ) @@ -163,7 +163,7 @@ class WorkflowTransitionViewTestMixin(object): class WorkflowViewTestMixin(object): def _request_test_workflow_create_view(self): return self.post( - viewname='document_states:setup_workflow_create', data={ + viewname='document_states:workflow_template_create', data={ 'label': TEST_WORKFLOW_LABEL, 'internal_name': TEST_WORKFLOW_INTERNAL_NAME, } @@ -171,14 +171,14 @@ class WorkflowViewTestMixin(object): def _request_test_workflow_delete_view(self): return self.post( - viewname='document_states:setup_workflow_delete', kwargs={ + viewname='document_states:workflow_template_delete', kwargs={ 'pk': self.test_workflow.pk } ) def _request_test_workflow_edit_view(self): return self.post( - viewname='document_states:setup_workflow_edit', kwargs={ + viewname='document_states:workflow_template_edit', kwargs={ 'pk': self.test_workflow.pk, }, data={ 'label': TEST_WORKFLOW_LABEL_EDITED, @@ -188,12 +188,12 @@ class WorkflowViewTestMixin(object): def _request_test_workflow_list_view(self): return self.get( - viewname='document_states:setup_workflow_list', + viewname='document_states:workflow_template_list', ) - def _request_test_workflow_preview_view(self): + def _request_test_workflow_template_preview_view(self): return self.get( - viewname='document_states:workflow_preview', kwargs={ + viewname='document_states:workflow_template_preview', kwargs={ 'pk': self.test_workflow.pk, } ) diff --git a/mayan/apps/document_states/tests/test_workflow_state_action_views.py b/mayan/apps/document_states/tests/test_workflow_state_action_views.py index e79853fd90..c1b54093a8 100644 --- a/mayan/apps/document_states/tests/test_workflow_state_action_views.py +++ b/mayan/apps/document_states/tests/test_workflow_state_action_views.py @@ -15,7 +15,7 @@ class WorkflowStateActionViewTestCase(WorkflowStateActionTestMixin, WorkflowTest def _request_test_document_state_action_view(self): return self.get( - viewname='document_states:setup_workflow_state_action_list', + viewname='document_states:workflow_template_state_action_list', kwargs={'pk': self.test_workflow_state.pk} ) diff --git a/mayan/apps/document_states/tests/test_workflow_transition_views.py b/mayan/apps/document_states/tests/test_workflow_transition_views.py index c298e5dde4..c4a004871c 100644 --- a/mayan/apps/document_states/tests/test_workflow_transition_views.py +++ b/mayan/apps/document_states/tests/test_workflow_transition_views.py @@ -212,7 +212,7 @@ class WorkflowTransitionEventViewTestCase( ): def _request_test_workflow_transition_event_list_view(self): return self.get( - viewname='document_states:setup_workflow_transition_events', + viewname='document_states:workflow_template_transition_events', kwargs={'pk': self.test_workflow_transition.pk} ) @@ -256,7 +256,7 @@ class WorkflowTransitionFieldViewTestCase( def _request_test_workflow_transition_field_list_view(self): return self.get( - viewname='document_states:setup_workflow_transition_field_list', + viewname='document_states:workflow_template_transition_field_list', kwargs={'pk': self.test_workflow_transition.pk} ) @@ -286,7 +286,7 @@ class WorkflowTransitionFieldViewTestCase( def _request_workflow_transition_field_create_view(self): return self.post( - viewname='document_states:setup_workflow_transition_field_create', + viewname='document_states:workflow_template_transition_field_create', kwargs={'pk': self.test_workflow_transition.pk}, data={ 'field_type': TEST_WORKFLOW_TRANSITION_FIELD_TYPE, @@ -324,7 +324,7 @@ class WorkflowTransitionFieldViewTestCase( def _request_workflow_transition_field_delete_view(self): return self.post( - viewname='document_states:setup_workflow_transition_field_delete', + viewname='document_states:workflow_template_transition_field_delete', kwargs={'pk': self.test_workflow_transition_field.pk}, ) diff --git a/mayan/apps/document_states/tests/test_workflow_views.py b/mayan/apps/document_states/tests/test_workflow_views.py index 24df83a095..1e738d7d53 100644 --- a/mayan/apps/document_states/tests/test_workflow_views.py +++ b/mayan/apps/document_states/tests/test_workflow_views.py @@ -93,31 +93,31 @@ class WorkflowViewTestCase( self.assertEqual(response.status_code, 200) self.assertContains(response, text=self.test_workflow.label) - def test_workflow_preview_view_no_access(self): + def test_workflow_template_preview_view_no_access(self): self._create_test_workflow() - response = self._request_test_workflow_preview_view() + response = self._request_test_workflow_template_preview_view() self.assertEqual(response.status_code, 404) self.assertTrue(self.test_workflow in Workflow.objects.all()) - def test_workflow_preview_view_with_access(self): + def test_workflow_template_preview_view_with_access(self): self._create_test_workflow() self.grant_access( obj=self.test_workflow, permission=permission_workflow_view ) - response = self._request_test_workflow_preview_view() + response = self._request_test_workflow_template_preview_view() self.assertEqual(response.status_code, 200) class WorkflowToolViewTestCase(WorkflowTestMixin, GenericDocumentViewTestCase): def _request_workflow_launch_view(self): return self.post( - viewname='document_states:tool_launch_all_workflows', + viewname='document_states:tool_launch_workflows', ) - def test_tool_launch_all_workflows_view_no_permission(self): + def test_tool_launch_workflows_view_no_permission(self): self._create_test_workflow(add_document_type=True) self._create_test_workflow_states() self._create_test_workflow_transition() @@ -129,7 +129,7 @@ class WorkflowToolViewTestCase(WorkflowTestMixin, GenericDocumentViewTestCase): self.assertEqual(self.test_document.workflows.count(), 0) - def test_tool_launch_all_workflows_view_with_permission(self): + def test_tool_launch_workflows_view_with_permission(self): self._create_test_workflow(add_document_type=True) self._create_test_workflow_states() self._create_test_workflow_transition() diff --git a/mayan/apps/document_states/urls.py b/mayan/apps/document_states/urls.py index 9dab2abd22..6b36dd490c 100644 --- a/mayan/apps/document_states/urls.py +++ b/mayan/apps/document_states/urls.py @@ -3,136 +3,57 @@ from __future__ import unicode_literals from django.conf.urls import url from .api_views import ( - APIDocumentTypeWorkflowListView, APIWorkflowDocumentTypeList, + APIDocumentTypeWorkflowRuntimeProxyListView, APIWorkflowDocumentTypeList, APIWorkflowDocumentTypeView, APIWorkflowImageView, APIWorkflowInstanceListView, APIWorkflowInstanceView, - APIWorkflowInstanceLogEntryListView, APIWorkflowListView, + APIWorkflowInstanceLogEntryListView, APIWorkflowRuntimeProxyListView, APIWorkflowStateListView, APIWorkflowStateView, APIWorkflowTransitionListView, APIWorkflowTransitionView, APIWorkflowView ) -from .views import ( - DocumentWorkflowInstanceListView, SetupWorkflowCreateView, - SetupWorkflowDeleteView, SetupWorkflowDocumentTypesView, - SetupWorkflowEditView, SetupWorkflowListView, - SetupWorkflowStateActionCreateView, SetupWorkflowStateActionDeleteView, - SetupWorkflowStateActionEditView, SetupWorkflowStateActionListView, - SetupWorkflowStateActionSelectionView, SetupWorkflowStateCreateView, - SetupWorkflowStateDeleteView, SetupWorkflowStateEditView, - SetupWorkflowStateListView, SetupWorkflowTransitionListView, - SetupWorkflowTransitionCreateView, SetupWorkflowTransitionDeleteView, - SetupWorkflowTransitionEditView, - SetupWorkflowTransitionTriggerEventListView, ToolLaunchAllWorkflows, - WorkflowDocumentListView, WorkflowInstanceDetailView, - WorkflowInstanceTransitionExecuteView, WorkflowInstanceTransitionSelectView, - WorkflowListView, WorkflowPreviewView, WorkflowStateDocumentListView, - WorkflowStateListView, +from .views.workflow_instance_views import ( + WorkflowInstanceDetailView, WorkflowInstanceListView, + WorkflowInstanceTransitionSelectView, + WorkflowInstanceTransitionExecuteView ) -from .views.workflow_views import ( - SetupDocumentTypeWorkflowsView, SetupWorkflowTransitionFieldCreateView, - SetupWorkflowTransitionFieldDeleteView, - SetupWorkflowTransitionFieldEditView, SetupWorkflowTransitionFieldListView +from .views.workflow_proxy_views import ( + WorkflowRuntimeProxyDocumentListView, + WorkflowRuntimeProxyListView, WorkflowRuntimeProxyStateDocumentListView, + WorkflowRuntimeProxyStateListView +) +from .views.workflow_template_views import ( + DocumentTypeWorkflowTemplatesView, ToolLaunchWorkflows, + WorkflowTemplateCreateView, WorkflowTemplateDeleteView, + WorkflowTemplateEditView, WorkflowTemplateListView, + WorkflowTemplatePreviewView, WorkflowTemplateDocumentTypesView +) +from .views.workflow_template_state_views import ( + WorkflowTemplateStateActionCreateView, + WorkflowTemplateStateActionDeleteView, WorkflowTemplateStateActionEditView, + WorkflowTemplateStateActionListView, + WorkflowTemplateStateActionSelectionView, WorkflowTemplateStateCreateView, + WorkflowTemplateStateDeleteView, WorkflowTemplateStateEditView, + WorkflowTemplateStateListView +) +from .views.workflow_template_transition_views import ( + WorkflowTemplateTransitionCreateView, WorkflowTemplateTransitionDeleteView, + WorkflowTemplateTransitionEditView, WorkflowTemplateTransitionListView, + WorkflowTemplateTransitionTriggerEventListView, + WorkflowTemplateTransitionFieldCreateView, + WorkflowTemplateTransitionFieldDeleteView, + WorkflowTemplateTransitionFieldEditView, + WorkflowTemplateTransitionFieldListView ) -urlpatterns_workflow_templates = [ +urlpatterns_workflow_instances = [ url( - regex=r'^setup/workflows/$', view=SetupWorkflowListView.as_view(), - name='setup_workflow_list' + regex=r'^documents/(?P\d+)/workflows/$', + view=WorkflowInstanceListView.as_view(), + name='workflow_instance_list' ), url( - regex=r'^setup/workflows/create/$', view=SetupWorkflowCreateView.as_view(), - name='setup_workflow_create' - ), - url( - regex=r'^setup/workflows/(?P\d+)/delete/$', - view=SetupWorkflowDeleteView.as_view(), name='setup_workflow_delete' - ), - url( - regex=r'^setup/workflows/(?P\d+)/edit/$', - view=SetupWorkflowEditView.as_view(), name='setup_workflow_edit' - ), - url( - regex=r'^setup/document_types/(?P\d+)/workflows/$', - view=SetupDocumentTypeWorkflowsView.as_view(), - name='document_type_workflows' - ), -] - -urlpatterns_workflow_states = [ - url( - regex=r'^setup/workflows/(?P\d+)/states/$', - view=SetupWorkflowStateListView.as_view(), - name='setup_workflow_state_list' - ), - url( - regex=r'^setup/workflows/(?P\d+)/states/create/$', - view=SetupWorkflowStateCreateView.as_view(), - name='setup_workflow_state_create' - ), - url( - regex=r'^setup/workflows/states/(?P\d+)/delete/$', - view=SetupWorkflowStateDeleteView.as_view(), - name='setup_workflow_state_delete' - ), - url( - regex=r'^setup/workflows/states/(?P\d+)/edit/$', - view=SetupWorkflowStateEditView.as_view(), - name='setup_workflow_state_edit' - ), -] - -urlpatterns_workflow_state_actions = [ - url( - regex=r'^setup/workflows/states/(?P\d+)/actions/$', - view=SetupWorkflowStateActionListView.as_view(), - name='setup_workflow_state_action_list' - ), - url( - regex=r'^setup/workflows/states/(?P\d+)/actions/selection/$', - view=SetupWorkflowStateActionSelectionView.as_view(), - name='setup_workflow_state_action_selection' - ), - url( - regex=r'^setup/workflows/states/(?P\d+)/actions/(?P[a-zA-Z0-9_.]+)/create/$', - view=SetupWorkflowStateActionCreateView.as_view(), - name='setup_workflow_state_action_create' - ), - url( - regex=r'^setup/workflows/states/actions/(?P\d+)/delete/$', - view=SetupWorkflowStateActionDeleteView.as_view(), - name='setup_workflow_state_action_delete' - ), - url( - regex=r'^setup/workflows/states/actions/(?P\d+)/edit/$', - view=SetupWorkflowStateActionEditView.as_view(), - name='setup_workflow_state_action_edit' - ), -] - -urlpatterns_workflow_transitions = [ - url( - regex=r'^setup/workflows/(?P\d+)/transitions/$', - view=SetupWorkflowTransitionListView.as_view(), - name='setup_workflow_transition_list' - ), - url( - regex=r'^setup/workflows/(?P\d+)/transitions/create/$', - view=SetupWorkflowTransitionCreateView.as_view(), - name='setup_workflow_transition_create' - ), - url( - regex=r'^setup/workflows/(?P\d+)/transitions/events/$', - view=SetupWorkflowTransitionTriggerEventListView.as_view(), - name='setup_workflow_transition_events' - ), - url( - regex=r'^setup/workflows/transitions/(?P\d+)/delete/$', - view=SetupWorkflowTransitionDeleteView.as_view(), - name='setup_workflow_transition_delete' - ), - url( - regex=r'^setup/workflows/transitions/(?P\d+)/edit/$', - view=SetupWorkflowTransitionEditView.as_view(), - name='setup_workflow_transition_edit' + regex=r'^documents/workflows/(?P\d+)/$', + view=WorkflowInstanceDetailView.as_view(), + name='workflow_instance_detail' ), url( regex=r'^documents/workflows/(?P\d+)/transitions/select/$', @@ -146,82 +67,174 @@ urlpatterns_workflow_transitions = [ ), ] +urlpatterns_workflow_runtime_proxies = [ + url( + regex=r'workflow_runtime_proxies/$', + view=WorkflowRuntimeProxyListView.as_view(), + name='workflow_runtime_proxy_list' + ), + url( + regex=r'^workflow_runtime_proxies/(?P\d+)/documents/$', + view=WorkflowRuntimeProxyDocumentListView.as_view(), + name='workflow_runtime_proxy_document_list' + ), + url( + regex=r'^workflow_runtime_proxies/(?P\d+)/states/$', + view=WorkflowRuntimeProxyStateListView.as_view(), + name='workflow_runtime_proxy_state_list' + ), + url( + regex=r'^workflow_runtime_proxies/states/(?P\d+)/documents/$', + view=WorkflowRuntimeProxyStateDocumentListView.as_view(), + name='workflow_runtime_proxy_state_document_list' + ), +] + +urlpatterns_workflow_states = [ + url( + regex=r'^workflow_templates/(?P\d+)/states/$', + view=WorkflowTemplateStateListView.as_view(), + name='workflow_template_state_list' + ), + url( + regex=r'^workflow_templates/(?P\d+)/states/create/$', + view=WorkflowTemplateStateCreateView.as_view(), + name='workflow_template_state_create' + ), + url( + regex=r'^workflow_templates/states/(?P\d+)/delete/$', + view=WorkflowTemplateStateDeleteView.as_view(), + name='workflow_template_state_delete' + ), + url( + regex=r'^workflow_templates/states/(?P\d+)/edit/$', + view=WorkflowTemplateStateEditView.as_view(), + name='workflow_template_state_edit' + ), +] + +urlpatterns_workflow_state_actions = [ + url( + regex=r'^workflow_templates/states/(?P\d+)/actions/$', + view=WorkflowTemplateStateActionListView.as_view(), + name='workflow_template_state_action_list' + ), + url( + regex=r'^workflow_templates/states/(?P\d+)/actions/selection/$', + view=WorkflowTemplateStateActionSelectionView.as_view(), + name='workflow_template_state_action_selection' + ), + url( + regex=r'^workflow_templates/states/(?P\d+)/actions/(?P[a-zA-Z0-9_.]+)/create/$', + view=WorkflowTemplateStateActionCreateView.as_view(), + name='workflow_template_state_action_create' + ), + url( + regex=r'^workflow_templates/states/actions/(?P\d+)/delete/$', + view=WorkflowTemplateStateActionDeleteView.as_view(), + name='workflow_template_state_action_delete' + ), + url( + regex=r'^workflow_templates/states/actions/(?P\d+)/edit/$', + view=WorkflowTemplateStateActionEditView.as_view(), + name='workflow_template_state_action_edit' + ), +] + +urlpatterns_workflow_templates = [ + url( + regex=r'^workflow_templates/$', view=WorkflowTemplateListView.as_view(), + name='workflow_template_list' + ), + url( + regex=r'^workflow_templates/create/$', view=WorkflowTemplateCreateView.as_view(), + name='workflow_template_create' + ), + url( + regex=r'^workflow_templates/(?P\d+)/delete/$', + view=WorkflowTemplateDeleteView.as_view(), name='workflow_template_delete' + ), + url( + regex=r'^workflow_templates/(?P\d+)/document_types/$', + view=WorkflowTemplateDocumentTypesView.as_view(), + name='workflow_template_document_types' + ), + url( + regex=r'^workflow_templates/(?P\d+)/edit/$', + view=WorkflowTemplateEditView.as_view(), name='workflow_template_edit' + ), + url( + regex=r'^workflow_templates/(?P\d+)/preview/$', + view=WorkflowTemplatePreviewView.as_view(), + name='workflow_template_preview' + ), + url( + regex=r'^document_types/(?P\d+)/workflow_templates/$', + view=DocumentTypeWorkflowTemplatesView.as_view(), + name='document_type_workflow_templates' + ), +] +urlpatterns_workflow_transitions = [ + url( + regex=r'^workflow_templates/(?P\d+)/transitions/$', + view=WorkflowTemplateTransitionListView.as_view(), + name='workflow_template_transition_list' + ), + url( + regex=r'^workflow_templates/(?P\d+)/transitions/create/$', + view=WorkflowTemplateTransitionCreateView.as_view(), + name='workflow_template_transition_create' + ), + url( + regex=r'^workflow_templates/(?P\d+)/transitions/events/$', + view=WorkflowTemplateTransitionTriggerEventListView.as_view(), + name='workflow_template_transition_events' + ), + url( + regex=r'^workflow_templates/transitions/(?P\d+)/delete/$', + view=WorkflowTemplateTransitionDeleteView.as_view(), + name='workflow_template_transition_delete' + ), + url( + regex=r'^workflow_templates/transitions/(?P\d+)/edit/$', + view=WorkflowTemplateTransitionEditView.as_view(), + name='workflow_template_transition_edit' + ), +] + urlpatterns_workflow_transition_fields = [ url( - regex=r'^setup/workflows/transitions/(?P\d+)/fields/create/$', - view=SetupWorkflowTransitionFieldCreateView.as_view(), - name='setup_workflow_transition_field_create' + regex=r'^workflow_templates/transitions/(?P\d+)/fields/create/$', + view=WorkflowTemplateTransitionFieldCreateView.as_view(), + name='workflow_template_transition_field_create' ), url( - regex=r'^setup/workflows/transitions/(?P\d+)/fields/$', - view=SetupWorkflowTransitionFieldListView.as_view(), - name='setup_workflow_transition_field_list' + regex=r'^workflow_templates/transitions/(?P\d+)/fields/$', + view=WorkflowTemplateTransitionFieldListView.as_view(), + name='workflow_template_transition_field_list' ), url( - regex=r'^setup/workflows/transitions/fields/(?P\d+)/delete/$', - view=SetupWorkflowTransitionFieldDeleteView.as_view(), - name='setup_workflow_transition_field_delete' + regex=r'^workflow_templates/transitions/fields/(?P\d+)/delete/$', + view=WorkflowTemplateTransitionFieldDeleteView.as_view(), + name='workflow_template_transition_field_delete' ), url( - regex=r'^setup/workflows/transitions/fields/(?P\d+)/edit/$', - view=SetupWorkflowTransitionFieldEditView.as_view(), - name='setup_workflow_transition_field_edit' + regex=r'^workflow_templates/transitions/fields/(?P\d+)/edit/$', + view=WorkflowTemplateTransitionFieldEditView.as_view(), + name='workflow_template_transition_field_edit' ), ] urlpatterns = [ url( - regex=r'^document/(?P\d+)/workflows/$', - view=DocumentWorkflowInstanceListView.as_view(), - name='document_workflow_instance_list' - ), - url( - regex=r'^document/workflows/(?P\d+)/$', - view=WorkflowInstanceDetailView.as_view(), - name='workflow_instance_detail' - ), - url( - regex=r'^setup/workflow/(?P\d+)/documents/$', - view=WorkflowDocumentListView.as_view(), - name='setup_workflow_document_list' - ), - url( - regex=r'^setup/workflow/(?P\d+)/document_types/$', - view=SetupWorkflowDocumentTypesView.as_view(), - name='setup_workflow_document_types' - ), - url( - regex=r'^tools/workflow/all/launch/$', - view=ToolLaunchAllWorkflows.as_view(), - name='tool_launch_all_workflows' - ), - url( - regex=r'all/$', - view=WorkflowListView.as_view(), - name='workflow_list' - ), - url( - regex=r'^(?P\d+)/documents/$', - view=WorkflowDocumentListView.as_view(), - name='workflow_document_list' - ), - url( - regex=r'^(?P\d+)/states/$', - view=WorkflowStateListView.as_view(), - name='workflow_state_list' - ), - url( - regex=r'^(?P\d+)/preview/$', - view=WorkflowPreviewView.as_view(), - name='workflow_preview' - ), - url( - regex=r'^state/(?P\d+)/documents/$', - view=WorkflowStateDocumentListView.as_view(), - name='workflow_state_document_list' + regex=r'^tools/workflows/launch/$', + view=ToolLaunchWorkflows.as_view(), + name='tool_launch_workflows' ), ] +urlpatterns.extend(urlpatterns_workflow_instances) +urlpatterns.extend(urlpatterns_workflow_runtime_proxies) urlpatterns.extend(urlpatterns_workflow_states) urlpatterns.extend(urlpatterns_workflow_state_actions) urlpatterns.extend(urlpatterns_workflow_templates) @@ -230,7 +243,7 @@ urlpatterns.extend(urlpatterns_workflow_transition_fields) api_urls = [ url( - regex=r'^workflows/$', view=APIWorkflowListView.as_view(), + regex=r'^workflows/$', view=APIWorkflowRuntimeProxyListView.as_view(), name='workflow-list' ), url( @@ -286,7 +299,7 @@ api_urls = [ ), url( regex=r'^document_types/(?P[0-9]+)/workflows/$', - view=APIDocumentTypeWorkflowListView.as_view(), + view=APIDocumentTypeWorkflowRuntimeProxyListView.as_view(), name='documenttype-workflow-list' ), ] diff --git a/mayan/apps/document_states/views/__init__.py b/mayan/apps/document_states/views/__init__.py index d6e36751b2..8b13789179 100644 --- a/mayan/apps/document_states/views/__init__.py +++ b/mayan/apps/document_states/views/__init__.py @@ -1,3 +1 @@ -from .workflow_instance_views import * # NOQA -from .workflow_proxy_views import * # NOQA -from .workflow_views import * # NOQA + diff --git a/mayan/apps/document_states/views/workflow_instance_views.py b/mayan/apps/document_states/views/workflow_instance_views.py index bed57fdcbc..6fcfd38fbd 100644 --- a/mayan/apps/document_states/views/workflow_instance_views.py +++ b/mayan/apps/document_states/views/workflow_instance_views.py @@ -14,20 +14,14 @@ from mayan.apps.common.mixins import ExternalObjectMixin from mayan.apps.documents.models import Document from ..forms import WorkflowInstanceTransitionSelectForm -from ..icons import icon_workflow_instance_detail, icon_workflow_list +from ..icons import icon_workflow_instance_detail, icon_workflow_template_list from ..links import link_workflow_instance_transition from ..literals import FIELD_TYPE_MAPPING, WIDGET_CLASS_MAPPING from ..models import WorkflowInstance from ..permissions import permission_workflow_view -__all__ = ( - 'DocumentWorkflowInstanceListView', 'WorkflowInstanceDetailView', - 'WorkflowInstanceTransitionSelectView', - 'WorkflowInstanceTransitionExecuteView' -) - -class DocumentWorkflowInstanceListView(SingleObjectListView): +class WorkflowInstanceListView(SingleObjectListView): def dispatch(self, request, *args, **kwargs): AccessControlList.objects.check_access( obj=self.get_document(), permissions=(permission_workflow_view,), @@ -35,7 +29,7 @@ class DocumentWorkflowInstanceListView(SingleObjectListView): ) return super( - DocumentWorkflowInstanceListView, self + WorkflowInstanceListView, self ).dispatch(request, *args, **kwargs) def get_document(self): @@ -44,7 +38,7 @@ class DocumentWorkflowInstanceListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, - 'no_results_icon': icon_workflow_list, + 'no_results_icon': icon_workflow_template_list, 'no_results_text': _( 'Assign workflows to the document type of this document ' 'to have this document execute those workflows. ' diff --git a/mayan/apps/document_states/views/workflow_proxy_views.py b/mayan/apps/document_states/views/workflow_proxy_views.py index 21efa2bb9e..77bd864ea4 100644 --- a/mayan/apps/document_states/views/workflow_proxy_views.py +++ b/mayan/apps/document_states/views/workflow_proxy_views.py @@ -9,18 +9,13 @@ from mayan.apps.common.generics import SingleObjectListView from mayan.apps.documents.models import Document from mayan.apps.documents.views import DocumentListView -from ..icons import icon_workflow_list -from ..links import link_setup_workflow_create, link_setup_workflow_state_create +from ..icons import icon_workflow_template_list +from ..links import link_workflow_template_create, link_workflow_template_state_create from ..models import WorkflowRuntimeProxy, WorkflowStateRuntimeProxy from ..permissions import permission_workflow_view -__all__ = ( - 'WorkflowDocumentListView', 'WorkflowListView', - 'WorkflowStateDocumentListView', 'WorkflowStateListView' -) - -class WorkflowDocumentListView(DocumentListView): +class WorkflowRuntimeProxyDocumentListView(DocumentListView): def dispatch(self, request, *args, **kwargs): self.workflow = get_object_or_404( klass=WorkflowRuntimeProxy, pk=self.kwargs['pk'] @@ -32,14 +27,14 @@ class WorkflowDocumentListView(DocumentListView): ) return super( - WorkflowDocumentListView, self + WorkflowRuntimeProxyDocumentListView, self ).dispatch(request, *args, **kwargs) def get_document_queryset(self): return Document.objects.filter(workflows__workflow=self.workflow) def get_extra_context(self): - context = super(WorkflowDocumentListView, self).get_extra_context() + context = super(WorkflowRuntimeProxyDocumentListView, self).get_extra_context() context.update( { 'no_results_text': _( @@ -56,14 +51,14 @@ class WorkflowDocumentListView(DocumentListView): return context -class WorkflowListView(SingleObjectListView): +class WorkflowRuntimeProxyListView(SingleObjectListView): object_permission = permission_workflow_view def get_extra_context(self): return { 'hide_object': True, - 'no_results_icon': icon_workflow_list, - 'no_results_main_link': link_setup_workflow_create.resolve( + 'no_results_icon': icon_workflow_template_list, + 'no_results_main_link': link_workflow_template_create.resolve( context=RequestContext(request=self.request) ), 'no_results_text': _( @@ -79,13 +74,13 @@ class WorkflowListView(SingleObjectListView): return WorkflowRuntimeProxy.objects.all() -class WorkflowStateDocumentListView(DocumentListView): +class WorkflowRuntimeProxyStateDocumentListView(DocumentListView): def get_document_queryset(self): return self.get_workflow_state().get_documents() def get_extra_context(self): workflow_state = self.get_workflow_state() - context = super(WorkflowStateDocumentListView, self).get_extra_context() + context = super(WorkflowRuntimeProxyStateDocumentListView, self).get_extra_context() context.update( { 'object': workflow_state, @@ -118,7 +113,7 @@ class WorkflowStateDocumentListView(DocumentListView): return workflow_state -class WorkflowStateListView(SingleObjectListView): +class WorkflowRuntimeProxyStateListView(SingleObjectListView): def dispatch(self, request, *args, **kwargs): AccessControlList.objects.check_access( obj=self.get_workflow(), permissions=(permission_workflow_view,), @@ -126,14 +121,14 @@ class WorkflowStateListView(SingleObjectListView): ) return super( - WorkflowStateListView, self + WorkflowRuntimeProxyStateListView, self ).dispatch(request, *args, **kwargs) def get_extra_context(self): return { 'hide_link': True, 'hide_object': True, - 'no_results_main_link': link_setup_workflow_state_create.resolve( + 'no_results_main_link': link_workflow_template_state_create.resolve( context=RequestContext( request=self.request, dict_={'object': self.get_workflow()} ) diff --git a/mayan/apps/document_states/views/workflow_template_state_views.py b/mayan/apps/document_states/views/workflow_template_state_views.py new file mode 100644 index 0000000000..a0f1e3cec7 --- /dev/null +++ b/mayan/apps/document_states/views/workflow_template_state_views.py @@ -0,0 +1,326 @@ +from __future__ import absolute_import, unicode_literals + +from django.contrib import messages +from django.db import transaction +from django.http import Http404, HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.template import RequestContext +from django.urls import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.common.generics import ( + AddRemoveView, ConfirmView, FormView, SingleObjectCreateView, + SingleObjectDeleteView, SingleObjectDetailView, + SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView, + SingleObjectEditView, SingleObjectListView +) +from mayan.apps.common.mixins import ExternalObjectMixin +from mayan.apps.documents.events import event_document_type_edited +from mayan.apps.documents.models import DocumentType +from mayan.apps.documents.permissions import permission_document_type_edit +from mayan.apps.events.classes import EventType +from mayan.apps.events.models import StoredEventType + +from ..classes import WorkflowAction +from ..events import event_workflow_edited +from ..forms import ( + WorkflowActionSelectionForm, WorkflowForm, WorkflowPreviewForm, + WorkflowStateActionDynamicForm, WorkflowStateForm, WorkflowTransitionForm, + WorkflowTransitionTriggerEventRelationshipFormSet +) +from ..icons import ( + icon_workflow_template_list, icon_workflow_state, icon_workflow_state_action, + icon_workflow_transition, icon_workflow_transition_field +) +from ..links import ( + link_workflow_template_create, link_workflow_template_state_create, + link_workflow_template_state_action_selection, + link_workflow_template_transition_create, + link_workflow_template_transition_field_create, +) +from ..models import ( + Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition, + WorkflowTransitionField +) +from ..permissions import ( + permission_workflow_create, permission_workflow_delete, + permission_workflow_edit, permission_workflow_tools, + permission_workflow_view, +) +from ..tasks import task_launch_all_workflows + + +class WorkflowTemplateStateActionCreateView(SingleObjectDynamicFormCreateView): + form_class = WorkflowStateActionDynamicForm + object_permission = permission_workflow_edit + + def get_class(self): + try: + return WorkflowAction.get(name=self.kwargs['class_path']) + except KeyError: + raise Http404( + '{} class not found'.format(self.kwargs['class_path']) + ) + + def get_extra_context(self): + return { + 'navigation_object_list': ('object', 'workflow'), + 'object': self.get_object(), + 'title': _( + 'Create a "%s" workflow action' + ) % self.get_class().label, + 'workflow': self.get_object().workflow + } + + def get_form_extra_kwargs(self): + return { + 'request': self.request, + 'action_path': self.kwargs['class_path'] + } + + def get_form_schema(self): + return self.get_class()().get_form_schema(request=self.request) + + def get_instance_extra_data(self): + return { + 'action_path': self.kwargs['class_path'], + 'state': self.get_object() + } + + def get_object(self): + return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_state_action_list', + kwargs={'pk': self.get_object().pk} + ) + + +class WorkflowTemplateStateActionDeleteView(SingleObjectDeleteView): + model = WorkflowStateAction + object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'navigation_object_list': ( + 'object', 'workflow_state', 'workflow' + ), + 'object': self.get_object(), + 'title': _('Delete workflow state action: %s') % self.get_object(), + 'workflow': self.get_object().state.workflow, + 'workflow_state': self.get_object().state, + } + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_state_action_list', + kwargs={'pk': self.get_object().state.pk} + ) + + +class WorkflowTemplateStateActionEditView(SingleObjectDynamicFormEditView): + form_class = WorkflowStateActionDynamicForm + model = WorkflowStateAction + object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'navigation_object_list': ( + 'object', 'workflow_state', 'workflow' + ), + 'object': self.get_object(), + 'title': _('Edit workflow state action: %s') % self.get_object(), + 'workflow': self.get_object().state.workflow, + 'workflow_state': self.get_object().state, + } + + def get_form_extra_kwargs(self): + return { + 'request': self.request, + 'action_path': self.get_object().action_path, + } + + def get_form_schema(self): + return self.get_object().get_class_instance().get_form_schema( + request=self.request + ) + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_state_action_list', + kwargs={'pk': self.get_object().state.pk} + ) + + +class WorkflowTemplateStateActionListView(SingleObjectListView): + object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'hide_object': True, + 'navigation_object_list': ('object', 'workflow'), + 'no_results_icon': icon_workflow_state_action, + 'no_results_main_link': link_workflow_template_state_action_selection.resolve( + context=RequestContext( + request=self.request, dict_={ + 'object': self.get_workflow_state() + } + ) + ), + 'no_results_text': _( + 'Workflow state actions are macros that get executed when ' + 'documents enters or leaves the state in which they reside.' + ), + 'no_results_title': _( + 'There are no actions for this workflow state' + ), + 'object': self.get_workflow_state(), + 'title': _( + 'Actions for workflow state: %s' + ) % self.get_workflow_state(), + 'workflow': self.get_workflow_state().workflow, + } + + def get_form_schema(self): + return {'fields': self.get_class().fields} + + def get_source_queryset(self): + return self.get_workflow_state().actions.all() + + def get_workflow_state(self): + return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) + + +class WorkflowTemplateStateActionSelectionView(FormView): + form_class = WorkflowActionSelectionForm + view_permission = permission_workflow_edit + + def form_valid(self, form): + klass = form.cleaned_data['klass'] + return HttpResponseRedirect( + redirect_to=reverse( + viewname='document_states:workflow_template_state_action_create', + kwargs={'pk': self.get_object().pk, 'class_path': klass} + ) + ) + + def get_extra_context(self): + return { + 'navigation_object_list': ( + 'object', 'workflow' + ), + 'object': self.get_object(), + 'title': _('New workflow state action selection'), + 'workflow': self.get_object().workflow, + } + + def get_object(self): + return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) + + +class WorkflowTemplateStateCreateView(ExternalObjectMixin, SingleObjectCreateView): + external_object_class = Workflow + external_object_permission = permission_workflow_edit + external_object_pk_url_kwarg = 'pk' + form_class = WorkflowStateForm + + def get_extra_context(self): + return { + 'object': self.get_workflow(), + 'title': _( + 'Create states for workflow: %s' + ) % self.get_workflow() + } + + def get_instance_extra_data(self): + return {'workflow': self.get_workflow()} + + def get_source_queryset(self): + return self.get_workflow().states.all() + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_state_list', + kwargs={'pk': self.kwargs['pk']} + ) + + def get_workflow(self): + return self.external_object + + +class WorkflowTemplateStateDeleteView(SingleObjectDeleteView): + model = WorkflowState + object_permission = permission_workflow_edit + pk_url_kwarg = 'pk' + + def get_extra_context(self): + return { + 'navigation_object_list': ('object', 'workflow_instance'), + 'object': self.get_object(), + 'title': _( + 'Delete workflow state: %s?' + ) % self.object, + 'workflow_instance': self.get_object().workflow, + } + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_state_list', + kwargs={'pk': self.get_object().workflow.pk} + ) + + +class WorkflowTemplateStateEditView(SingleObjectEditView): + form_class = WorkflowStateForm + model = WorkflowState + object_permission = permission_workflow_edit + pk_url_kwarg = 'pk' + + def get_extra_context(self): + return { + 'navigation_object_list': ('object', 'workflow_instance'), + 'object': self.get_object(), + 'title': _( + 'Edit workflow state: %s' + ) % self.object, + 'workflow_instance': self.get_object().workflow, + } + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_state_list', + kwargs={'pk': self.get_object().workflow.pk} + ) + + +class WorkflowTemplateStateListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = Workflow + external_object_permission = permission_workflow_view + external_object_pk_url_kwarg = 'pk' + object_permission = permission_workflow_view + + def get_extra_context(self): + return { + 'hide_object': True, + 'no_results_icon': icon_workflow_state, + 'no_results_main_link': link_workflow_template_state_create.resolve( + context=RequestContext( + self.request, {'object': self.get_workflow()} + ) + ), + 'no_results_text': _( + 'Create states and link them using transitions.' + ), + 'no_results_title': _( + 'This workflow doesn\'t have any states' + ), + 'object': self.get_workflow(), + 'title': _('States of workflow: %s') % self.get_workflow() + } + + def get_source_queryset(self): + return self.get_workflow().states.all() + + def get_workflow(self): + return self.external_object diff --git a/mayan/apps/document_states/views/workflow_template_transition_views.py b/mayan/apps/document_states/views/workflow_template_transition_views.py new file mode 100644 index 0000000000..e56a10a625 --- /dev/null +++ b/mayan/apps/document_states/views/workflow_template_transition_views.py @@ -0,0 +1,372 @@ +from __future__ import absolute_import, unicode_literals + +from django.contrib import messages +from django.db import transaction +from django.http import Http404, HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.template import RequestContext +from django.urls import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.common.generics import ( + AddRemoveView, ConfirmView, FormView, SingleObjectCreateView, + SingleObjectDeleteView, SingleObjectDetailView, + SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView, + SingleObjectEditView, SingleObjectListView +) +from mayan.apps.common.mixins import ExternalObjectMixin +from mayan.apps.documents.events import event_document_type_edited +from mayan.apps.documents.models import DocumentType +from mayan.apps.documents.permissions import permission_document_type_edit +from mayan.apps.events.classes import EventType +from mayan.apps.events.models import StoredEventType + +from ..classes import WorkflowAction +from ..events import event_workflow_edited +from ..forms import ( + WorkflowActionSelectionForm, WorkflowForm, WorkflowPreviewForm, + WorkflowStateActionDynamicForm, WorkflowStateForm, WorkflowTransitionForm, + WorkflowTransitionTriggerEventRelationshipFormSet +) +from ..icons import ( + icon_workflow_template_list, icon_workflow_state, icon_workflow_state_action, + icon_workflow_transition, icon_workflow_transition_field +) +from ..links import ( + link_workflow_template_create, link_workflow_template_state_create, + link_workflow_template_state_action_selection, + link_workflow_template_transition_create, + link_workflow_template_transition_field_create, +) +from ..models import ( + Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition, + WorkflowTransitionField +) +from ..permissions import ( + permission_workflow_create, permission_workflow_delete, + permission_workflow_edit, permission_workflow_tools, + permission_workflow_view, +) +from ..tasks import task_launch_all_workflows + + +class WorkflowTemplateTransitionCreateView(ExternalObjectMixin, SingleObjectCreateView): + external_object_class = Workflow + external_object_permission = permission_workflow_edit + external_object_pk_url_kwarg = 'pk' + form_class = WorkflowTransitionForm + + def get_extra_context(self): + return { + 'object': self.get_workflow(), + 'title': _( + 'Create transitions for workflow: %s' + ) % self.get_workflow() + } + + def get_form_kwargs(self): + kwargs = super( + WorkflowTemplateTransitionCreateView, self + ).get_form_kwargs() + kwargs['workflow'] = self.get_workflow() + return kwargs + + def get_instance_extra_data(self): + return {'workflow': self.get_workflow()} + + def get_source_queryset(self): + return self.get_workflow().transitions.all() + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_transition_list', + kwargs={'pk': self.kwargs['pk']} + ) + + def get_workflow(self): + return self.external_object + + +class WorkflowTemplateTransitionDeleteView(SingleObjectDeleteView): + model = WorkflowTransition + object_permission = permission_workflow_edit + pk_url_kwarg = 'pk' + + def get_extra_context(self): + return { + 'object': self.get_object(), + 'navigation_object_list': ('object', 'workflow_instance'), + 'title': _( + 'Delete workflow transition: %s?' + ) % self.object, + 'workflow_instance': self.get_object().workflow, + } + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_transition_list', + kwargs={'pk': self.get_object().workflow.pk} + ) + + +class WorkflowTemplateTransitionEditView(SingleObjectEditView): + form_class = WorkflowTransitionForm + model = WorkflowTransition + object_permission = permission_workflow_edit + pk_url_kwarg = 'pk' + + def get_extra_context(self): + return { + 'navigation_object_list': ('object', 'workflow_instance'), + 'object': self.get_object(), + 'title': _( + 'Edit workflow transition: %s' + ) % self.object, + 'workflow_instance': self.get_object().workflow, + } + + def get_form_kwargs(self): + kwargs = super( + WorkflowTemplateTransitionEditView, self + ).get_form_kwargs() + kwargs['workflow'] = self.get_object().workflow + return kwargs + + def get_success_url(self): + return reverse( + viewname='document_states:workflow_template_transition_list', + kwargs={'pk': self.get_object().workflow.pk} + ) + + +class WorkflowTemplateTransitionListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = Workflow + external_object_permission = permission_workflow_view + external_object_pk_url_kwarg = 'pk' + object_permission = permission_workflow_view + + def get_extra_context(self): + return { + 'hide_object': True, + 'no_results_icon': icon_workflow_transition, + 'no_results_main_link': link_workflow_template_transition_create.resolve( + context=RequestContext( + self.request, {'object': self.get_workflow()} + ) + ), + 'no_results_text': _( + 'Create a transition and use it to move a workflow from ' + ' one state to another.' + ), + 'no_results_title': _( + 'This workflow doesn\'t have any transitions' + ), + 'object': self.get_workflow(), + 'title': _( + 'Transitions of workflow: %s' + ) % self.get_workflow() + } + + def get_source_queryset(self): + return self.get_workflow().transitions.all() + + def get_workflow(self): + return self.external_object + + +class WorkflowTemplateTransitionTriggerEventListView(ExternalObjectMixin, FormView): + external_object_class = WorkflowTransition + external_object_permission = permission_workflow_edit + external_object_pk_url_kwarg = 'pk' + form_class = WorkflowTransitionTriggerEventRelationshipFormSet + + def dispatch(self, *args, **kwargs): + EventType.refresh() + return super( + WorkflowTemplateTransitionTriggerEventListView, self + ).dispatch(*args, **kwargs) + + def form_valid(self, form): + try: + for instance in form: + instance.save() + except Exception as exception: + messages.error( + message=_( + 'Error updating workflow transition trigger events; %s' + ) % exception, request=self.request + + ) + else: + messages.success( + message=_( + 'Workflow transition trigger events updated successfully' + ), request=self.request + ) + + return super( + WorkflowTemplateTransitionTriggerEventListView, self + ).form_valid(form=form) + + def get_extra_context(self): + return { + 'form_display_mode_table': True, + 'navigation_object_list': ('object', 'workflow'), + 'object': self.get_object(), + 'subtitle': _( + 'Triggers are events that cause this transition to execute ' + 'automatically.' + ), + 'title': _( + 'Workflow transition trigger events for: %s' + ) % self.get_object(), + 'workflow': self.get_object().workflow, + } + + def get_initial(self): + obj = self.get_object() + initial = [] + + # Return the queryset by name from the sorted list of the class + event_type_ids = [event_type.id for event_type in EventType.all()] + event_type_queryset = StoredEventType.objects.filter( + name__in=event_type_ids + ) + + # Sort queryset in Python by namespace, then by label + event_type_queryset = sorted( + event_type_queryset, key=lambda x: (x.namespace, x.label) + ) + + for event_type in event_type_queryset: + initial.append({ + 'transition': obj, + 'event_type': event_type, + }) + return initial + + def get_object(self): + return self.external_object + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_transition_list', + kwargs={'pk': self.get_object().workflow.pk} + ) + + +class WorkflowTemplateTransitionFieldCreateView(ExternalObjectMixin, SingleObjectCreateView): + external_object_class = WorkflowTransition + external_object_permission = permission_workflow_edit + fields = ( + 'name', 'label', 'field_type', 'help_text', 'required', 'widget', + 'widget_kwargs' + ) + + def get_extra_context(self): + return { + 'navigation_object_list': ('transition', 'workflow'), + 'transition': self.external_object, + 'title': _( + 'Create a field for workflow transition: %s' + ) % self.external_object, + 'workflow': self.external_object.workflow + } + + def get_instance_extra_data(self): + return { + 'transition': self.external_object, + } + + def get_queryset(self): + return self.external_object.fields.all() + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_transition_field_list', + kwargs={'pk': self.external_object.pk} + ) + + +class WorkflowTemplateTransitionFieldDeleteView(SingleObjectDeleteView): + model = WorkflowTransitionField + object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'navigation_object_list': ( + 'object', 'workflow_transition', 'workflow' + ), + 'object': self.object, + 'title': _('Delete workflow transition field: %s') % self.object, + 'workflow': self.object.transition.workflow, + 'workflow_transition': self.object.transition, + } + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_transition_field_list', + kwargs={'pk': self.object.transition.pk} + ) + + +class WorkflowTemplateTransitionFieldEditView(SingleObjectEditView): + fields = ( + 'name', 'label', 'field_type', 'help_text', 'required', 'widget', + 'widget_kwargs' + ) + model = WorkflowTransitionField + object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'navigation_object_list': ( + 'object', 'workflow_transition', 'workflow' + ), + 'object': self.object, + 'title': _('Edit workflow transition field: %s') % self.object, + 'workflow': self.object.transition.workflow, + 'workflow_transition': self.object.transition, + } + + def get_post_action_redirect(self): + return reverse( + viewname='document_states:workflow_template_transition_field_list', + kwargs={'pk': self.object.transition.pk} + ) + + +class WorkflowTemplateTransitionFieldListView(ExternalObjectMixin, SingleObjectListView): + external_object_class = WorkflowTransition + external_object_permission = permission_workflow_edit + + def get_extra_context(self): + return { + 'hide_object': True, + 'navigation_object_list': ('object', 'workflow'), + 'no_results_icon': icon_workflow_transition_field, + 'no_results_main_link': link_workflow_template_transition_field_create.resolve( + context=RequestContext( + request=self.request, dict_={ + 'object': self.external_object + } + ) + ), + 'no_results_text': _( + 'Workflow transition fields allow adding data to the ' + 'workflow\'s context. This additional context data can then ' + 'be used by other elements of the workflow system like the ' + 'workflow state actions.' + ), + 'no_results_title': _( + 'There are no fields for this workflow transition' + ), + 'object': self.external_object, + 'title': _( + 'Fields for workflow transition: %s' + ) % self.external_object, + 'workflow': self.external_object.workflow, + } + + def get_source_queryset(self): + return self.external_object.fields.all() diff --git a/mayan/apps/document_states/views/workflow_template_views.py b/mayan/apps/document_states/views/workflow_template_views.py new file mode 100644 index 0000000000..e755f42e33 --- /dev/null +++ b/mayan/apps/document_states/views/workflow_template_views.py @@ -0,0 +1,261 @@ +from __future__ import absolute_import, unicode_literals + +from django.contrib import messages +from django.db import transaction +from django.http import Http404, HttpResponseRedirect +from django.shortcuts import get_object_or_404 +from django.template import RequestContext +from django.urls import reverse, reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.common.generics import ( + AddRemoveView, ConfirmView, FormView, SingleObjectCreateView, + SingleObjectDeleteView, SingleObjectDetailView, + SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView, + SingleObjectEditView, SingleObjectListView +) +from mayan.apps.common.mixins import ExternalObjectMixin +from mayan.apps.documents.events import event_document_type_edited +from mayan.apps.documents.models import DocumentType +from mayan.apps.documents.permissions import permission_document_type_edit +from mayan.apps.events.classes import EventType +from mayan.apps.events.models import StoredEventType + +from ..classes import WorkflowAction +from ..events import event_workflow_edited +from ..forms import ( + WorkflowActionSelectionForm, WorkflowForm, WorkflowPreviewForm, + WorkflowStateActionDynamicForm, WorkflowStateForm, WorkflowTransitionForm, + WorkflowTransitionTriggerEventRelationshipFormSet +) +from ..icons import ( + icon_workflow_template_list, icon_workflow_state, icon_workflow_state_action, + icon_workflow_transition, icon_workflow_transition_field +) +from ..links import ( + link_workflow_template_create, link_workflow_template_state_create, + link_workflow_template_state_action_selection, + link_workflow_template_transition_create, + link_workflow_template_transition_field_create, +) +from ..models import ( + Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition, + WorkflowTransitionField +) +from ..permissions import ( + permission_workflow_create, permission_workflow_delete, + permission_workflow_edit, permission_workflow_tools, + permission_workflow_view, +) +from ..tasks import task_launch_all_workflows + + +class DocumentTypeWorkflowTemplatesView(AddRemoveView): + main_object_permission = permission_document_type_edit + main_object_model = DocumentType + main_object_pk_url_kwarg = 'pk' + secondary_object_model = Workflow + secondary_object_permission = permission_workflow_edit + list_available_title = _('Available workflows') + list_added_title = _('Workflows assigned this document type') + related_field = 'workflows' + + def get_actions_extra_kwargs(self): + return {'_user': self.request.user} + + def get_extra_context(self): + return { + 'object': self.main_object, + 'subtitle': _( + 'Removing a workflow from a document type will also ' + 'remove all running instances of that workflow.' + ), + 'title': _( + 'Workflows assigned the document type: %s' + ) % self.main_object, + } + + def action_add(self, queryset, _user): + with transaction.atomic(): + event_document_type_edited.commit( + actor=_user, target=self.main_object + ) + + for obj in queryset: + self.main_object.workflows.add(obj) + event_workflow_edited.commit( + action_object=self.main_object, actor=_user, target=obj + ) + + def action_remove(self, queryset, _user): + with transaction.atomic(): + event_document_type_edited.commit( + actor=_user, target=self.main_object + ) + + for obj in queryset: + self.main_object.workflows.remove(obj) + event_workflow_edited.commit( + action_object=self.main_object, actor=_user, + target=obj + ) + obj.instances.filter( + document__document_type=self.main_object + ).delete() + + +class WorkflowTemplateListView(SingleObjectListView): + model = Workflow + object_permission = permission_workflow_view + + def get_extra_context(self): + return { + 'hide_object': True, + 'no_results_icon': icon_workflow_template_list, + 'no_results_main_link': link_workflow_template_create.resolve( + context=RequestContext(request=self.request) + ), + 'no_results_text': _( + 'Workflows store a series of states and keep track of the ' + 'current state of a document. Transitions are used to change the ' + 'current state to a new one.' + ), + 'no_results_title': _( + 'No workflows have been defined' + ), + 'title': _('Workflows'), + } + + +class WorkflowTemplateCreateView(SingleObjectCreateView): + extra_context = {'title': _('Create workflow')} + form_class = WorkflowForm + model = Workflow + post_action_redirect = reverse_lazy( + viewname='document_states:workflow_template_list' + ) + view_permission = permission_workflow_create + + def get_save_extra_data(self): + return {'_user': self.request.user} + + +class WorkflowTemplateDeleteView(SingleObjectDeleteView): + model = Workflow + object_permission = permission_workflow_delete + post_action_redirect = reverse_lazy( + viewname='document_states:workflow_template_list' + ) + + def get_extra_context(self): + return { + 'title': _( + 'Delete workflow: %s?' + ) % self.object, + } + + +class WorkflowTemplateEditView(SingleObjectEditView): + form_class = WorkflowForm + model = Workflow + object_permission = permission_workflow_edit + post_action_redirect = reverse_lazy( + viewname='document_states:workflow_template_list' + ) + + def get_extra_context(self): + return { + 'title': _( + 'Edit workflow: %s' + ) % self.object, + } + + def get_save_extra_data(self): + return {'_user': self.request.user} + + +class WorkflowTemplateDocumentTypesView(AddRemoveView): + main_object_permission = permission_workflow_edit + main_object_model = Workflow + main_object_pk_url_kwarg = 'pk' + secondary_object_model = DocumentType + secondary_object_permission = permission_document_type_edit + list_available_title = _('Available document types') + list_added_title = _('Document types assigned this workflow') + related_field = 'document_types' + + def get_actions_extra_kwargs(self): + return {'_user': self.request.user} + + def get_extra_context(self): + return { + 'object': self.main_object, + 'subtitle': _( + 'Removing a document type from a workflow will also ' + 'remove all running instances of that workflow for ' + 'documents of the document type just removed.' + ), + 'title': _( + 'Document types assigned the workflow: %s' + ) % self.main_object, + } + + def action_add(self, queryset, _user): + with transaction.atomic(): + event_workflow_edited.commit( + actor=_user, target=self.main_object + ) + + for obj in queryset: + self.main_object.document_types.add(obj) + event_document_type_edited.commit( + action_object=self.main_object, actor=_user, target=obj + ) + + def action_remove(self, queryset, _user): + with transaction.atomic(): + event_workflow_edited.commit( + actor=_user, target=self.main_object + ) + + for obj in queryset: + self.main_object.document_types.remove(obj) + event_document_type_edited.commit( + action_object=self.main_object, actor=_user, + target=obj + ) + self.main_object.instances.filter( + document__document_type=obj + ).delete() + + +class WorkflowTemplatePreviewView(SingleObjectDetailView): + form_class = WorkflowPreviewForm + model = Workflow + object_permission = permission_workflow_view + pk_url_kwarg = 'pk' + + def get_extra_context(self): + return { + 'hide_labels': True, + 'object': self.get_object(), + 'title': _('Preview of: %s') % self.get_object() + } + + +class ToolLaunchWorkflows(ConfirmView): + extra_context = { + 'title': _('Launch all workflows?'), + 'subtitle': _( + 'This will launch all workflows created after documents have ' + 'already been uploaded.' + ) + } + view_permission = permission_workflow_tools + + def view_action(self): + task_launch_all_workflows.apply_async() + messages.success( + message=_('Workflow launch queued successfully.'), + request=self.request + ) diff --git a/mayan/apps/document_states/views/workflow_views.py b/mayan/apps/document_states/views/workflow_views.py deleted file mode 100644 index 104560a805..0000000000 --- a/mayan/apps/document_states/views/workflow_views.py +++ /dev/null @@ -1,884 +0,0 @@ -from __future__ import absolute_import, unicode_literals - -from django.contrib import messages -from django.db import transaction -from django.http import Http404, HttpResponseRedirect -from django.shortcuts import get_object_or_404 -from django.template import RequestContext -from django.urls import reverse, reverse_lazy -from django.utils.translation import ugettext_lazy as _ - -from mayan.apps.common.generics import ( - AddRemoveView, ConfirmView, FormView, SingleObjectCreateView, - SingleObjectDeleteView, SingleObjectDetailView, - SingleObjectDynamicFormCreateView, SingleObjectDynamicFormEditView, - SingleObjectEditView, SingleObjectListView -) -from mayan.apps.common.mixins import ExternalObjectMixin -from mayan.apps.documents.events import event_document_type_edited -from mayan.apps.documents.models import DocumentType -from mayan.apps.documents.permissions import permission_document_type_edit -from mayan.apps.events.classes import EventType -from mayan.apps.events.models import StoredEventType - -from ..classes import WorkflowAction -from ..events import event_workflow_edited -from ..forms import ( - WorkflowActionSelectionForm, WorkflowForm, WorkflowPreviewForm, - WorkflowStateActionDynamicForm, WorkflowStateForm, WorkflowTransitionForm, - WorkflowTransitionTriggerEventRelationshipFormSet -) -from ..icons import ( - icon_workflow_list, icon_workflow_state, icon_workflow_state_action, - icon_workflow_transition, icon_workflow_transition_field -) -from ..links import ( - link_setup_workflow_create, link_setup_workflow_state_create, - link_setup_workflow_state_action_selection, - link_setup_workflow_transition_create, - link_setup_workflow_transition_field_create, -) -from ..models import ( - Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition, - WorkflowTransitionField -) -from ..permissions import ( - permission_workflow_create, permission_workflow_delete, - permission_workflow_edit, permission_workflow_tools, - permission_workflow_view, -) -from ..tasks import task_launch_all_workflows - -__all__ = ( - 'SetupWorkflowListView', 'SetupWorkflowCreateView', 'SetupWorkflowEditView', - 'SetupWorkflowDeleteView', 'SetupWorkflowDocumentTypesView', - 'SetupWorkflowStateActionCreateView', 'SetupWorkflowStateActionDeleteView', - 'SetupWorkflowStateActionEditView', 'SetupWorkflowStateActionListView', - 'SetupWorkflowStateActionSelectionView', 'SetupWorkflowStateCreateView', - 'SetupWorkflowStateDeleteView', 'SetupWorkflowStateEditView', - 'SetupWorkflowStateListView', 'SetupWorkflowTransitionCreateView', - 'SetupWorkflowTransitionDeleteView', 'SetupWorkflowTransitionEditView', - 'SetupWorkflowTransitionListView', - 'SetupWorkflowTransitionTriggerEventListView', 'ToolLaunchAllWorkflows', - 'WorkflowPreviewView' -) - - -class SetupDocumentTypeWorkflowsView(AddRemoveView): - main_object_permission = permission_document_type_edit - main_object_model = DocumentType - main_object_pk_url_kwarg = 'pk' - secondary_object_model = Workflow - secondary_object_permission = permission_workflow_edit - list_available_title = _('Available workflows') - list_added_title = _('Workflows assigned this document type') - related_field = 'workflows' - - def get_actions_extra_kwargs(self): - return {'_user': self.request.user} - - def get_extra_context(self): - return { - 'object': self.main_object, - 'subtitle': _( - 'Removing a workflow from a document type will also ' - 'remove all running instances of that workflow.' - ), - 'title': _( - 'Workflows assigned the document type: %s' - ) % self.main_object, - } - - def action_add(self, queryset, _user): - with transaction.atomic(): - event_document_type_edited.commit( - actor=_user, target=self.main_object - ) - - for obj in queryset: - self.main_object.workflows.add(obj) - event_workflow_edited.commit( - action_object=self.main_object, actor=_user, target=obj - ) - - def action_remove(self, queryset, _user): - with transaction.atomic(): - event_document_type_edited.commit( - actor=_user, target=self.main_object - ) - - for obj in queryset: - self.main_object.workflows.remove(obj) - event_workflow_edited.commit( - action_object=self.main_object, actor=_user, - target=obj - ) - obj.instances.filter( - document__document_type=self.main_object - ).delete() - - -class SetupWorkflowListView(SingleObjectListView): - model = Workflow - object_permission = permission_workflow_view - - def get_extra_context(self): - return { - 'hide_object': True, - 'no_results_icon': icon_workflow_list, - 'no_results_main_link': link_setup_workflow_create.resolve( - context=RequestContext(request=self.request) - ), - 'no_results_text': _( - 'Workflows store a series of states and keep track of the ' - 'current state of a document. Transitions are used to change the ' - 'current state to a new one.' - ), - 'no_results_title': _( - 'No workflows have been defined' - ), - 'title': _('Workflows'), - } - - -class SetupWorkflowCreateView(SingleObjectCreateView): - extra_context = {'title': _('Create workflow')} - form_class = WorkflowForm - model = Workflow - post_action_redirect = reverse_lazy( - viewname='document_states:setup_workflow_list' - ) - view_permission = permission_workflow_create - - def get_save_extra_data(self): - return {'_user': self.request.user} - - -class SetupWorkflowDeleteView(SingleObjectDeleteView): - model = Workflow - object_permission = permission_workflow_delete - post_action_redirect = reverse_lazy( - viewname='document_states:setup_workflow_list' - ) - - def get_extra_context(self): - return { - 'title': _( - 'Delete workflow: %s?' - ) % self.object, - } - - -class SetupWorkflowEditView(SingleObjectEditView): - form_class = WorkflowForm - model = Workflow - object_permission = permission_workflow_edit - post_action_redirect = reverse_lazy( - viewname='document_states:setup_workflow_list' - ) - - def get_extra_context(self): - return { - 'title': _( - 'Edit workflow: %s' - ) % self.object, - } - - def get_save_extra_data(self): - return {'_user': self.request.user} - - -class SetupWorkflowDocumentTypesView(AddRemoveView): - main_object_permission = permission_workflow_edit - main_object_model = Workflow - main_object_pk_url_kwarg = 'pk' - secondary_object_model = DocumentType - secondary_object_permission = permission_document_type_edit - list_available_title = _('Available document types') - list_added_title = _('Document types assigned this workflow') - related_field = 'document_types' - - def get_actions_extra_kwargs(self): - return {'_user': self.request.user} - - def get_extra_context(self): - return { - 'object': self.main_object, - 'subtitle': _( - 'Removing a document type from a workflow will also ' - 'remove all running instances of that workflow for ' - 'documents of the document type just removed.' - ), - 'title': _( - 'Document types assigned the workflow: %s' - ) % self.main_object, - } - - def action_add(self, queryset, _user): - with transaction.atomic(): - event_workflow_edited.commit( - actor=_user, target=self.main_object - ) - - for obj in queryset: - self.main_object.document_types.add(obj) - event_document_type_edited.commit( - action_object=self.main_object, actor=_user, target=obj - ) - - def action_remove(self, queryset, _user): - with transaction.atomic(): - event_workflow_edited.commit( - actor=_user, target=self.main_object - ) - - for obj in queryset: - self.main_object.document_types.remove(obj) - event_document_type_edited.commit( - action_object=self.main_object, actor=_user, - target=obj - ) - self.main_object.instances.filter( - document__document_type=obj - ).delete() - - -# Workflow state actions - - -class SetupWorkflowStateActionCreateView(SingleObjectDynamicFormCreateView): - form_class = WorkflowStateActionDynamicForm - object_permission = permission_workflow_edit - - def get_class(self): - try: - return WorkflowAction.get(name=self.kwargs['class_path']) - except KeyError: - raise Http404( - '{} class not found'.format(self.kwargs['class_path']) - ) - - def get_extra_context(self): - return { - 'navigation_object_list': ('object', 'workflow'), - 'object': self.get_object(), - 'title': _( - 'Create a "%s" workflow action' - ) % self.get_class().label, - 'workflow': self.get_object().workflow - } - - def get_form_extra_kwargs(self): - return { - 'request': self.request, - 'action_path': self.kwargs['class_path'] - } - - def get_form_schema(self): - return self.get_class()().get_form_schema(request=self.request) - - def get_instance_extra_data(self): - return { - 'action_path': self.kwargs['class_path'], - 'state': self.get_object() - } - - def get_object(self): - return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_state_action_list', - kwargs={'pk': self.get_object().pk} - ) - - -class SetupWorkflowStateActionDeleteView(SingleObjectDeleteView): - model = WorkflowStateAction - object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'navigation_object_list': ( - 'object', 'workflow_state', 'workflow' - ), - 'object': self.get_object(), - 'title': _('Delete workflow state action: %s') % self.get_object(), - 'workflow': self.get_object().state.workflow, - 'workflow_state': self.get_object().state, - } - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_state_action_list', - kwargs={'pk': self.get_object().state.pk} - ) - - -class SetupWorkflowStateActionEditView(SingleObjectDynamicFormEditView): - form_class = WorkflowStateActionDynamicForm - model = WorkflowStateAction - object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'navigation_object_list': ( - 'object', 'workflow_state', 'workflow' - ), - 'object': self.get_object(), - 'title': _('Edit workflow state action: %s') % self.get_object(), - 'workflow': self.get_object().state.workflow, - 'workflow_state': self.get_object().state, - } - - def get_form_extra_kwargs(self): - return { - 'request': self.request, - 'action_path': self.get_object().action_path, - } - - def get_form_schema(self): - return self.get_object().get_class_instance().get_form_schema( - request=self.request - ) - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_state_action_list', - kwargs={'pk': self.get_object().state.pk} - ) - - -class SetupWorkflowStateActionListView(SingleObjectListView): - object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'hide_object': True, - 'navigation_object_list': ('object', 'workflow'), - 'no_results_icon': icon_workflow_state_action, - 'no_results_main_link': link_setup_workflow_state_action_selection.resolve( - context=RequestContext( - request=self.request, dict_={ - 'object': self.get_workflow_state() - } - ) - ), - 'no_results_text': _( - 'Workflow state actions are macros that get executed when ' - 'documents enters or leaves the state in which they reside.' - ), - 'no_results_title': _( - 'There are no actions for this workflow state' - ), - 'object': self.get_workflow_state(), - 'title': _( - 'Actions for workflow state: %s' - ) % self.get_workflow_state(), - 'workflow': self.get_workflow_state().workflow, - } - - def get_form_schema(self): - return {'fields': self.get_class().fields} - - def get_source_queryset(self): - return self.get_workflow_state().actions.all() - - def get_workflow_state(self): - return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) - - -class SetupWorkflowStateActionSelectionView(FormView): - form_class = WorkflowActionSelectionForm - view_permission = permission_workflow_edit - - def form_valid(self, form): - klass = form.cleaned_data['klass'] - return HttpResponseRedirect( - redirect_to=reverse( - viewname='document_states:setup_workflow_state_action_create', - kwargs={'pk': self.get_object().pk, 'class_path': klass} - ) - ) - - def get_extra_context(self): - return { - 'navigation_object_list': ( - 'object', 'workflow' - ), - 'object': self.get_object(), - 'title': _('New workflow state action selection'), - 'workflow': self.get_object().workflow, - } - - def get_object(self): - return get_object_or_404(klass=WorkflowState, pk=self.kwargs['pk']) - - -# Workflow states - - -class SetupWorkflowStateCreateView(ExternalObjectMixin, SingleObjectCreateView): - external_object_class = Workflow - external_object_permission = permission_workflow_edit - external_object_pk_url_kwarg = 'pk' - form_class = WorkflowStateForm - - def get_extra_context(self): - return { - 'object': self.get_workflow(), - 'title': _( - 'Create states for workflow: %s' - ) % self.get_workflow() - } - - def get_instance_extra_data(self): - return {'workflow': self.get_workflow()} - - def get_source_queryset(self): - return self.get_workflow().states.all() - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_state_list', - kwargs={'pk': self.kwargs['pk']} - ) - - def get_workflow(self): - return self.external_object - - -class SetupWorkflowStateDeleteView(SingleObjectDeleteView): - model = WorkflowState - object_permission = permission_workflow_edit - pk_url_kwarg = 'pk' - - def get_extra_context(self): - return { - 'navigation_object_list': ('object', 'workflow_instance'), - 'object': self.get_object(), - 'title': _( - 'Delete workflow state: %s?' - ) % self.object, - 'workflow_instance': self.get_object().workflow, - } - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_state_list', - kwargs={'pk': self.get_object().workflow.pk} - ) - - -class SetupWorkflowStateEditView(SingleObjectEditView): - form_class = WorkflowStateForm - model = WorkflowState - object_permission = permission_workflow_edit - pk_url_kwarg = 'pk' - - def get_extra_context(self): - return { - 'navigation_object_list': ('object', 'workflow_instance'), - 'object': self.get_object(), - 'title': _( - 'Edit workflow state: %s' - ) % self.object, - 'workflow_instance': self.get_object().workflow, - } - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_state_list', - kwargs={'pk': self.get_object().workflow.pk} - ) - - -class SetupWorkflowStateListView(ExternalObjectMixin, SingleObjectListView): - external_object_class = Workflow - external_object_permission = permission_workflow_view - external_object_pk_url_kwarg = 'pk' - object_permission = permission_workflow_view - - def get_extra_context(self): - return { - 'hide_object': True, - 'no_results_icon': icon_workflow_state, - 'no_results_main_link': link_setup_workflow_state_create.resolve( - context=RequestContext( - self.request, {'object': self.get_workflow()} - ) - ), - 'no_results_text': _( - 'Create states and link them using transitions.' - ), - 'no_results_title': _( - 'This workflow doesn\'t have any states' - ), - 'object': self.get_workflow(), - 'title': _('States of workflow: %s') % self.get_workflow() - } - - def get_source_queryset(self): - return self.get_workflow().states.all() - - def get_workflow(self): - return self.external_object - - -# Transitions - - -class SetupWorkflowTransitionCreateView(ExternalObjectMixin, SingleObjectCreateView): - external_object_class = Workflow - external_object_permission = permission_workflow_edit - external_object_pk_url_kwarg = 'pk' - form_class = WorkflowTransitionForm - - def get_extra_context(self): - return { - 'object': self.get_workflow(), - 'title': _( - 'Create transitions for workflow: %s' - ) % self.get_workflow() - } - - def get_form_kwargs(self): - kwargs = super( - SetupWorkflowTransitionCreateView, self - ).get_form_kwargs() - kwargs['workflow'] = self.get_workflow() - return kwargs - - def get_instance_extra_data(self): - return {'workflow': self.get_workflow()} - - def get_source_queryset(self): - return self.get_workflow().transitions.all() - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_transition_list', - kwargs={'pk': self.kwargs['pk']} - ) - - def get_workflow(self): - return self.external_object - - -class SetupWorkflowTransitionDeleteView(SingleObjectDeleteView): - model = WorkflowTransition - object_permission = permission_workflow_edit - pk_url_kwarg = 'pk' - - def get_extra_context(self): - return { - 'object': self.get_object(), - 'navigation_object_list': ('object', 'workflow_instance'), - 'title': _( - 'Delete workflow transition: %s?' - ) % self.object, - 'workflow_instance': self.get_object().workflow, - } - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_transition_list', - kwargs={'pk': self.get_object().workflow.pk} - ) - - -class SetupWorkflowTransitionEditView(SingleObjectEditView): - form_class = WorkflowTransitionForm - model = WorkflowTransition - object_permission = permission_workflow_edit - pk_url_kwarg = 'pk' - - def get_extra_context(self): - return { - 'navigation_object_list': ('object', 'workflow_instance'), - 'object': self.get_object(), - 'title': _( - 'Edit workflow transition: %s' - ) % self.object, - 'workflow_instance': self.get_object().workflow, - } - - def get_form_kwargs(self): - kwargs = super( - SetupWorkflowTransitionEditView, self - ).get_form_kwargs() - kwargs['workflow'] = self.get_object().workflow - return kwargs - - def get_success_url(self): - return reverse( - viewname='document_states:setup_workflow_transition_list', - kwargs={'pk': self.get_object().workflow.pk} - ) - - -class SetupWorkflowTransitionListView(ExternalObjectMixin, SingleObjectListView): - external_object_class = Workflow - external_object_permission = permission_workflow_view - external_object_pk_url_kwarg = 'pk' - object_permission = permission_workflow_view - - def get_extra_context(self): - return { - 'hide_object': True, - 'no_results_icon': icon_workflow_transition, - 'no_results_main_link': link_setup_workflow_transition_create.resolve( - context=RequestContext( - self.request, {'object': self.get_workflow()} - ) - ), - 'no_results_text': _( - 'Create a transition and use it to move a workflow from ' - ' one state to another.' - ), - 'no_results_title': _( - 'This workflow doesn\'t have any transitions' - ), - 'object': self.get_workflow(), - 'title': _( - 'Transitions of workflow: %s' - ) % self.get_workflow() - } - - def get_source_queryset(self): - return self.get_workflow().transitions.all() - - def get_workflow(self): - return self.external_object - - -class SetupWorkflowTransitionTriggerEventListView(ExternalObjectMixin, FormView): - external_object_class = WorkflowTransition - external_object_permission = permission_workflow_edit - external_object_pk_url_kwarg = 'pk' - form_class = WorkflowTransitionTriggerEventRelationshipFormSet - - def dispatch(self, *args, **kwargs): - EventType.refresh() - return super( - SetupWorkflowTransitionTriggerEventListView, self - ).dispatch(*args, **kwargs) - - def form_valid(self, form): - try: - for instance in form: - instance.save() - except Exception as exception: - messages.error( - message=_( - 'Error updating workflow transition trigger events; %s' - ) % exception, request=self.request - - ) - else: - messages.success( - message=_( - 'Workflow transition trigger events updated successfully' - ), request=self.request - ) - - return super( - SetupWorkflowTransitionTriggerEventListView, self - ).form_valid(form=form) - - def get_extra_context(self): - return { - 'form_display_mode_table': True, - 'navigation_object_list': ('object', 'workflow'), - 'object': self.get_object(), - 'subtitle': _( - 'Triggers are events that cause this transition to execute ' - 'automatically.' - ), - 'title': _( - 'Workflow transition trigger events for: %s' - ) % self.get_object(), - 'workflow': self.get_object().workflow, - } - - def get_initial(self): - obj = self.get_object() - initial = [] - - # Return the queryset by name from the sorted list of the class - event_type_ids = [event_type.id for event_type in EventType.all()] - event_type_queryset = StoredEventType.objects.filter( - name__in=event_type_ids - ) - - # Sort queryset in Python by namespace, then by label - event_type_queryset = sorted( - event_type_queryset, key=lambda x: (x.namespace, x.label) - ) - - for event_type in event_type_queryset: - initial.append({ - 'transition': obj, - 'event_type': event_type, - }) - return initial - - def get_object(self): - return self.external_object - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_transition_list', - kwargs={'pk': self.get_object().workflow.pk} - ) - - -# Transition fields - -class SetupWorkflowTransitionFieldCreateView(ExternalObjectMixin, SingleObjectCreateView): - external_object_class = WorkflowTransition - external_object_permission = permission_workflow_edit - fields = ( - 'name', 'label', 'field_type', 'help_text', 'required', 'widget', - 'widget_kwargs' - ) - - def get_extra_context(self): - return { - 'navigation_object_list': ('transition', 'workflow'), - 'transition': self.external_object, - 'title': _( - 'Create a field for workflow transition: %s' - ) % self.external_object, - 'workflow': self.external_object.workflow - } - - def get_instance_extra_data(self): - return { - 'transition': self.external_object, - } - - def get_queryset(self): - return self.external_object.fields.all() - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_transition_field_list', - kwargs={'pk': self.external_object.pk} - ) - - -class SetupWorkflowTransitionFieldDeleteView(SingleObjectDeleteView): - model = WorkflowTransitionField - object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'navigation_object_list': ( - 'object', 'workflow_transition', 'workflow' - ), - 'object': self.object, - 'title': _('Delete workflow transition field: %s') % self.object, - 'workflow': self.object.transition.workflow, - 'workflow_transition': self.object.transition, - } - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_transition_field_list', - kwargs={'pk': self.object.transition.pk} - ) - - -class SetupWorkflowTransitionFieldEditView(SingleObjectEditView): - fields = ( - 'name', 'label', 'field_type', 'help_text', 'required', 'widget', - 'widget_kwargs' - ) - model = WorkflowTransitionField - object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'navigation_object_list': ( - 'object', 'workflow_transition', 'workflow' - ), - 'object': self.object, - 'title': _('Edit workflow transition field: %s') % self.object, - 'workflow': self.object.transition.workflow, - 'workflow_transition': self.object.transition, - } - - def get_post_action_redirect(self): - return reverse( - viewname='document_states:setup_workflow_transition_field_list', - kwargs={'pk': self.object.transition.pk} - ) - - -class SetupWorkflowTransitionFieldListView(ExternalObjectMixin, SingleObjectListView): - external_object_class = WorkflowTransition - external_object_permission = permission_workflow_edit - - def get_extra_context(self): - return { - 'hide_object': True, - 'navigation_object_list': ('object', 'workflow'), - 'no_results_icon': icon_workflow_transition_field, - 'no_results_main_link': link_setup_workflow_transition_field_create.resolve( - context=RequestContext( - request=self.request, dict_={ - 'object': self.external_object - } - ) - ), - 'no_results_text': _( - 'Workflow transition fields allow adding data to the ' - 'workflow\'s context. This additional context data can then ' - 'be used by other elements of the workflow system like the ' - 'workflow state actions.' - ), - 'no_results_title': _( - 'There are no fields for this workflow transition' - ), - 'object': self.external_object, - 'title': _( - 'Fields for workflow transition: %s' - ) % self.external_object, - 'workflow': self.external_object.workflow, - } - - def get_source_queryset(self): - return self.external_object.fields.all() - - -class ToolLaunchAllWorkflows(ConfirmView): - extra_context = { - 'title': _('Launch all workflows?'), - 'subtitle': _( - 'This will launch all workflows created after documents have ' - 'already been uploaded.' - ) - } - view_permission = permission_workflow_tools - - def view_action(self): - task_launch_all_workflows.apply_async() - messages.success( - message=_('Workflow launch queued successfully.'), - request=self.request - ) - - -class WorkflowPreviewView(SingleObjectDetailView): - form_class = WorkflowPreviewForm - model = Workflow - object_permission = permission_workflow_view - pk_url_kwarg = 'pk' - - def get_extra_context(self): - return { - 'hide_labels': True, - 'object': self.get_object(), - 'title': _('Preview of: %s') % self.get_object() - } diff --git a/mayan/apps/mailer/tests/test_actions.py b/mayan/apps/mailer/tests/test_actions.py index eed6d9f49a..cf21f68b0d 100644 --- a/mayan/apps/mailer/tests/test_actions.py +++ b/mayan/apps/mailer/tests/test_actions.py @@ -139,7 +139,7 @@ class EmailActionViewTestCase(DocumentTestMixin, MailerTestMixin, WorkflowTestMi self._create_test_user_mailer() response = self.get( - viewname='document_states:setup_workflow_state_action_create', + viewname='document_states:workflow_template_state_action_create', kwargs={ 'pk': self.test_workflow_state.pk, 'class_path': 'mayan.apps.mailer.workflow_actions.EmailAction', @@ -151,7 +151,7 @@ class EmailActionViewTestCase(DocumentTestMixin, MailerTestMixin, WorkflowTestMi def _request_email_action_create_post_view(self): return self.post( - viewname='document_states:setup_workflow_state_action_create', + viewname='document_states:workflow_template_state_action_create', kwargs={ 'pk': self.test_workflow_state.pk, 'class_path': 'mayan.apps.mailer.workflow_actions.EmailAction', diff --git a/mayan/apps/tags/tests/test_actions.py b/mayan/apps/tags/tests/test_actions.py index 0aa8c55078..ec0fe3caa5 100644 --- a/mayan/apps/tags/tests/test_actions.py +++ b/mayan/apps/tags/tests/test_actions.py @@ -39,7 +39,7 @@ class TagActionViewTestCase(WorkflowTestMixin, GenericViewTestCase): self._create_test_workflow_state() response = self.get( - viewname='document_states:setup_workflow_state_action_create', + viewname='document_states:workflow_template_state_action_create', kwargs={ 'pk': self.test_workflow_state.pk, 'class_path': 'mayan.apps.tags.workflow_actions.AttachTagAction' @@ -53,7 +53,7 @@ class TagActionViewTestCase(WorkflowTestMixin, GenericViewTestCase): self._create_test_workflow_state() response = self.get( - viewname='document_states:setup_workflow_state_action_create', + viewname='document_states:workflow_template_state_action_create', kwargs={ 'pk': self.test_workflow_state.pk, 'class_path': 'mayan.apps.tags.workflow_actions.RemoveTagAction'