Add field type selection
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -157,6 +157,9 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
ModelPermission.register_inheritance(
|
ModelPermission.register_inheritance(
|
||||||
model=WorkflowTransition, related='workflow',
|
model=WorkflowTransition, related='workflow',
|
||||||
)
|
)
|
||||||
|
ModelPermission.register_inheritance(
|
||||||
|
model=WorkflowTransitionField, related='transition',
|
||||||
|
)
|
||||||
ModelPermission.register_inheritance(
|
ModelPermission.register_inheritance(
|
||||||
model=WorkflowTransitionTriggerEvent,
|
model=WorkflowTransitionTriggerEvent,
|
||||||
related='transition__workflow',
|
related='transition__workflow',
|
||||||
@@ -206,16 +209,20 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
attribute='datetime'
|
attribute='datetime'
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstanceLogEntry, label=_('User'), attribute='user'
|
source=WorkflowInstanceLogEntry, attribute='user'
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstanceLogEntry, label=_('Transition'),
|
source=WorkflowInstanceLogEntry,
|
||||||
attribute='transition'
|
attribute='transition'
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstanceLogEntry, label=_('Comment'),
|
source=WorkflowInstanceLogEntry,
|
||||||
attribute='comment'
|
attribute='comment'
|
||||||
)
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=WorkflowInstanceLogEntry,
|
||||||
|
attribute='extra_data'
|
||||||
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
attribute='label', is_sortable=True, source=WorkflowState
|
attribute='label', is_sortable=True, source=WorkflowState
|
||||||
@@ -269,6 +276,10 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
SourceColumn(
|
SourceColumn(
|
||||||
attribute='label', is_sortable=True, source=WorkflowTransitionField
|
attribute='label', is_sortable=True, source=WorkflowTransitionField
|
||||||
)
|
)
|
||||||
|
SourceColumn(
|
||||||
|
attribute='get_field_type_display', label=_('Type'),
|
||||||
|
source=WorkflowTransitionField
|
||||||
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
attribute='required', is_sortable=True, source=WorkflowTransitionField,
|
attribute='required', is_sortable=True, source=WorkflowTransitionField,
|
||||||
widget=TwoStateWidget
|
widget=TwoStateWidget
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ class WorkflowInstanceTransitionSelectForm(forms.Form):
|
|||||||
].queryset = workflow_instance.get_transition_choices(_user=user)
|
].queryset = workflow_instance.get_transition_choices(_user=user)
|
||||||
|
|
||||||
transition = forms.ModelChoiceField(
|
transition = forms.ModelChoiceField(
|
||||||
|
help_text=_('Select a transition to execute in the next step.'),
|
||||||
label=_('Transition'), queryset=WorkflowTransition.objects.none()
|
label=_('Transition'), queryset=WorkflowTransition.objects.none()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ icon_workflow_list = Icon(driver_name='fontawesome', symbol='sitemap')
|
|||||||
icon_workflow_preview = Icon(driver_name='fontawesome', symbol='eye')
|
icon_workflow_preview = Icon(driver_name='fontawesome', symbol='eye')
|
||||||
|
|
||||||
|
|
||||||
icon_workflow_instance_detail = Icon(driver_name='fontawesome', symbol='sitemap')
|
icon_workflow_instance_detail = Icon(
|
||||||
|
driver_name='fontawesome', symbol='sitemap'
|
||||||
|
)
|
||||||
icon_workflow_instance_transition = Icon(
|
icon_workflow_instance_transition = Icon(
|
||||||
driver_name='fontawesome', symbol='arrows-alt-h'
|
driver_name='fontawesome', symbol='arrows-alt-h'
|
||||||
)
|
)
|
||||||
@@ -58,8 +60,12 @@ icon_workflow_state_delete = Icon(driver_name='fontawesome', symbol='times')
|
|||||||
icon_workflow_state_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
icon_workflow_state_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
||||||
|
|
||||||
icon_workflow_state_action = Icon(driver_name='fontawesome', symbol='code')
|
icon_workflow_state_action = Icon(driver_name='fontawesome', symbol='code')
|
||||||
icon_workflow_state_action_delete = Icon(driver_name='fontawesome', symbol='times')
|
icon_workflow_state_action_delete = Icon(
|
||||||
icon_workflow_state_action_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
driver_name='fontawesome', symbol='times'
|
||||||
|
)
|
||||||
|
icon_workflow_state_action_edit = Icon(
|
||||||
|
driver_name='fontawesome', symbol='pencil-alt'
|
||||||
|
)
|
||||||
icon_workflow_state_action_selection = Icon(
|
icon_workflow_state_action_selection = Icon(
|
||||||
driver_name='fontawesome-dual', primary_symbol='code',
|
driver_name='fontawesome-dual', primary_symbol='code',
|
||||||
secondary_symbol='plus'
|
secondary_symbol='plus'
|
||||||
@@ -72,19 +78,27 @@ icon_workflow_transition_create = Icon(
|
|||||||
driver_name='fontawesome-dual', primary_symbol='arrows-alt-h',
|
driver_name='fontawesome-dual', primary_symbol='arrows-alt-h',
|
||||||
secondary_symbol='plus'
|
secondary_symbol='plus'
|
||||||
)
|
)
|
||||||
icon_workflow_transition_delete = Icon(driver_name='fontawesome', symbol='times')
|
icon_workflow_transition_delete = Icon(
|
||||||
|
driver_name='fontawesome', symbol='times'
|
||||||
|
)
|
||||||
icon_workflow_transition_edit = Icon(
|
icon_workflow_transition_edit = Icon(
|
||||||
driver_name='fontawesome', symbol='pencil-alt'
|
driver_name='fontawesome', symbol='pencil-alt'
|
||||||
)
|
)
|
||||||
|
|
||||||
icon_workflow_transition_field = Icon(driver_name='fontawesome', symbol='code')
|
icon_workflow_transition_field = Icon(driver_name='fontawesome', symbol='table')
|
||||||
icon_workflow_transition_field_delete = Icon(driver_name='fontawesome', symbol='times')
|
icon_workflow_transition_field_delete = Icon(
|
||||||
icon_workflow_transition_field_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
driver_name='fontawesome', symbol='times'
|
||||||
|
)
|
||||||
|
icon_workflow_transition_field_edit = Icon(
|
||||||
|
driver_name='fontawesome', symbol='pencil-alt'
|
||||||
|
)
|
||||||
icon_workflow_transition_field_create = Icon(
|
icon_workflow_transition_field_create = Icon(
|
||||||
driver_name='fontawesome-dual', primary_symbol='code',
|
driver_name='fontawesome-dual', primary_symbol='table',
|
||||||
secondary_symbol='plus'
|
secondary_symbol='plus'
|
||||||
)
|
)
|
||||||
icon_workflow_transition_field_list = Icon(driver_name='fontawesome', symbol='code')
|
icon_workflow_transition_field_list = Icon(
|
||||||
|
driver_name='fontawesome', symbol='table'
|
||||||
|
)
|
||||||
|
|
||||||
icon_workflow_transition_triggers = Icon(
|
icon_workflow_transition_triggers = Icon(
|
||||||
driver_name='fontawesome', symbol='bolt'
|
driver_name='fontawesome', symbol='bolt'
|
||||||
|
|||||||
@@ -9,3 +9,15 @@ WORKFLOW_ACTION_WHEN_CHOICES = (
|
|||||||
(WORKFLOW_ACTION_ON_ENTRY, _('On entry')),
|
(WORKFLOW_ACTION_ON_ENTRY, _('On entry')),
|
||||||
(WORKFLOW_ACTION_ON_EXIT, _('On exit')),
|
(WORKFLOW_ACTION_ON_EXIT, _('On exit')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
FIELD_TYPE_CHOICE_CHAR = 1
|
||||||
|
FIELD_TYPE_CHOICE_INTEGER = 2
|
||||||
|
FIELD_TYPE_CHOICES = (
|
||||||
|
(FIELD_TYPE_CHOICE_CHAR, _('Character')),
|
||||||
|
(FIELD_TYPE_CHOICE_INTEGER, _('Number (Integer)')),
|
||||||
|
)
|
||||||
|
|
||||||
|
FIELD_TYPE_MAPPING = {
|
||||||
|
FIELD_TYPE_CHOICE_CHAR: 'django.forms.CharField',
|
||||||
|
FIELD_TYPE_CHOICE_INTEGER: 'django.forms.IntegerField',
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Generated by Django 1.11.20 on 2019-06-30 13:31
|
# Generated by Django 1.11.20 on 2019-07-01 04:54
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
@@ -17,10 +17,11 @@ class Migration(migrations.Migration):
|
|||||||
name='WorkflowTransitionField',
|
name='WorkflowTransitionField',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('name', models.CharField(max_length=128, verbose_name='Internal name')),
|
('field_type', models.PositiveIntegerField(choices=[(1, 'Character'), (2, 'Number (Integer)')], verbose_name='Type')),
|
||||||
('label', models.CharField(max_length=128, verbose_name='Label')),
|
('name', models.CharField(help_text='The name that will be used to identify this field in other parts of the workflow system.', max_length=128, verbose_name='Internal name')),
|
||||||
('help_text', models.TextField(blank=True, verbose_name='Help text')),
|
('label', models.CharField(help_text='The field name that will be shown on the user interface.', max_length=128, verbose_name='Label')),
|
||||||
('required', models.BooleanField(default=False, verbose_name='Required')),
|
('help_text', models.TextField(blank=True, help_text='An optional message that will help users better understand the purpose of the field and data to provide.', verbose_name='Help text')),
|
||||||
|
('required', models.BooleanField(default=False, help_text='Whether this fields needs to be filled out or not to proceed.', verbose_name='Required')),
|
||||||
('transition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='document_states.WorkflowTransition', verbose_name='Transition')),
|
('transition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='document_states.WorkflowTransition', verbose_name='Transition')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
@@ -33,6 +34,11 @@ class Migration(migrations.Migration):
|
|||||||
name='context',
|
name='context',
|
||||||
field=models.TextField(blank=True, verbose_name='Backend data'),
|
field=models.TextField(blank=True, verbose_name='Backend data'),
|
||||||
),
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='workflowinstancelogentry',
|
||||||
|
name='extra_data',
|
||||||
|
field=models.TextField(blank=True, verbose_name='Extra data'),
|
||||||
|
),
|
||||||
migrations.AlterUniqueTogether(
|
migrations.AlterUniqueTogether(
|
||||||
name='workflowtransitionfield',
|
name='workflowtransitionfield',
|
||||||
unique_together=set([('transition', 'name')]),
|
unique_together=set([('transition', 'name')]),
|
||||||
@@ -23,8 +23,8 @@ from mayan.apps.events.models import StoredEventType
|
|||||||
from .error_logs import error_log_state_actions
|
from .error_logs import error_log_state_actions
|
||||||
from .events import event_workflow_created, event_workflow_edited
|
from .events import event_workflow_created, event_workflow_edited
|
||||||
from .literals import (
|
from .literals import (
|
||||||
WORKFLOW_ACTION_WHEN_CHOICES, WORKFLOW_ACTION_ON_ENTRY,
|
FIELD_TYPE_CHOICES, WORKFLOW_ACTION_WHEN_CHOICES,
|
||||||
WORKFLOW_ACTION_ON_EXIT
|
WORKFLOW_ACTION_ON_ENTRY, WORKFLOW_ACTION_ON_EXIT
|
||||||
)
|
)
|
||||||
from .managers import WorkflowManager
|
from .managers import WorkflowManager
|
||||||
from .permissions import permission_workflow_transition
|
from .permissions import permission_workflow_transition
|
||||||
@@ -369,6 +369,9 @@ class WorkflowTransitionField(models.Model):
|
|||||||
on_delete=models.CASCADE, related_name='fields',
|
on_delete=models.CASCADE, related_name='fields',
|
||||||
to=WorkflowTransition, verbose_name=_('Transition')
|
to=WorkflowTransition, verbose_name=_('Transition')
|
||||||
)
|
)
|
||||||
|
field_type = models.PositiveIntegerField(
|
||||||
|
choices=FIELD_TYPE_CHOICES, verbose_name=_('Type')
|
||||||
|
)
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
help_text=_(
|
help_text=_(
|
||||||
'The name that will be used to identify this field in other parts '
|
'The name that will be used to identify this field in other parts '
|
||||||
@@ -390,7 +393,6 @@ class WorkflowTransitionField(models.Model):
|
|||||||
'Whether this fields needs to be filled out or not to proceed.'
|
'Whether this fields needs to be filled out or not to proceed.'
|
||||||
), verbose_name=_('Required')
|
), verbose_name=_('Required')
|
||||||
)
|
)
|
||||||
#TODO: widget, widget kwargs
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('transition', 'name')
|
unique_together = ('transition', 'name')
|
||||||
@@ -431,7 +433,7 @@ class WorkflowInstance(models.Model):
|
|||||||
verbose_name=_('Document')
|
verbose_name=_('Document')
|
||||||
)
|
)
|
||||||
context = models.TextField(
|
context = models.TextField(
|
||||||
blank=True, verbose_name=_('Backend data')
|
blank=True, verbose_name=_('Context')
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -447,25 +449,25 @@ class WorkflowInstance(models.Model):
|
|||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
try:
|
try:
|
||||||
if transition in self.get_current_state().origin_transitions.all():
|
if transition in self.get_current_state().origin_transitions.all():
|
||||||
self.log_entries.create(
|
|
||||||
comment=comment or '', transition=transition, user=user
|
|
||||||
)
|
|
||||||
if extra_data:
|
if extra_data:
|
||||||
data = self.loads()
|
context = self.loads()
|
||||||
data.update(extra_data)
|
context.update(extra_data)
|
||||||
self.dumps(data=data)
|
self.dumps(context=context)
|
||||||
|
|
||||||
|
self.log_entries.create(
|
||||||
|
comment=comment or '',
|
||||||
|
extra_data=json.dumps(extra_data or {}),
|
||||||
|
transition=transition, user=user
|
||||||
|
)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# No initial state has been set for this workflow
|
# No initial state has been set for this workflow
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# TODO: execute transition event target = document,
|
def dumps(self, context):
|
||||||
# action_object = self
|
|
||||||
|
|
||||||
def dumps(self, data):
|
|
||||||
"""
|
"""
|
||||||
Serialize the context data.
|
Serialize the context data.
|
||||||
"""
|
"""
|
||||||
self.context = json.dumps(data)
|
self.context = json.dumps(context)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
@@ -579,6 +581,7 @@ class WorkflowInstanceLogEntry(models.Model):
|
|||||||
to=settings.AUTH_USER_MODEL, verbose_name=_('User')
|
to=settings.AUTH_USER_MODEL, verbose_name=_('User')
|
||||||
)
|
)
|
||||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||||
|
extra_data = models.TextField(blank=True, verbose_name=_('Extra data'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('datetime',)
|
ordering = ('datetime',)
|
||||||
@@ -592,6 +595,12 @@ class WorkflowInstanceLogEntry(models.Model):
|
|||||||
if self.transition not in self.workflow_instance.get_transition_choices(_user=self.user):
|
if self.transition not in self.workflow_instance.get_transition_choices(_user=self.user):
|
||||||
raise ValidationError(_('Not a valid transition choice.'))
|
raise ValidationError(_('Not a valid transition choice.'))
|
||||||
|
|
||||||
|
def loads(self):
|
||||||
|
"""
|
||||||
|
Deserialize the context data.
|
||||||
|
"""
|
||||||
|
return json.loads(self.extra_data or '{}')
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
result = super(WorkflowInstanceLogEntry, self).save(*args, **kwargs)
|
result = super(WorkflowInstanceLogEntry, self).save(*args, **kwargs)
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ from .mixins import (
|
|||||||
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin
|
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TEST_WORKFLOW_TRANSITION_FIELD_NAME = 'test_workflow_transition_field'
|
||||||
|
TEST_WORKFLOW_TRANSITION_FIELD_LABEL = 'test workflow transition field'
|
||||||
|
TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT = 'test workflow transition field help test'
|
||||||
|
|
||||||
|
|
||||||
class WorkflowTransitionViewTestCase(
|
class WorkflowTransitionViewTestCase(
|
||||||
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin,
|
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin,
|
||||||
@@ -232,3 +236,123 @@ class WorkflowTransitionEventViewTestCase(
|
|||||||
|
|
||||||
response = self._request_test_workflow_transition_event_list_view()
|
response = self._request_test_workflow_transition_event_list_view()
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
|
class WorkflowTransitionFieldViewTestCase(
|
||||||
|
WorkflowTestMixin, WorkflowTransitionViewTestMixin, GenericViewTestCase
|
||||||
|
):
|
||||||
|
def setUp(self):
|
||||||
|
super(WorkflowTransitionFieldViewTestCase, self).setUp()
|
||||||
|
self._create_test_workflow()
|
||||||
|
self._create_test_workflow_states()
|
||||||
|
self._create_test_workflow_transition()
|
||||||
|
|
||||||
|
def _create_test_workflow_transition_field(self):
|
||||||
|
self.test_workflow_transition_field = self.test_workflow_transition.fields.create(
|
||||||
|
name=TEST_WORKFLOW_TRANSITION_FIELD_NAME,
|
||||||
|
label=TEST_WORKFLOW_TRANSITION_FIELD_LABEL,
|
||||||
|
help_text=TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT
|
||||||
|
)
|
||||||
|
|
||||||
|
def _request_test_workflow_transition_field_list_view(self):
|
||||||
|
return self.get(
|
||||||
|
viewname='document_states:setup_workflow_transition_field_list',
|
||||||
|
kwargs={'pk': self.test_workflow_transition.pk}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_list_view_no_permission(self):
|
||||||
|
self._create_test_workflow_transition_field()
|
||||||
|
|
||||||
|
response = self._request_test_workflow_transition_field_list_view()
|
||||||
|
self.assertNotContains(
|
||||||
|
response=response,
|
||||||
|
text=self.test_workflow_transition_field.label,
|
||||||
|
status_code=404
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_list_view_with_access(self):
|
||||||
|
self._create_test_workflow_transition_field()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_workflow, permission=permission_workflow_edit
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_test_workflow_transition_field_list_view()
|
||||||
|
self.assertContains(
|
||||||
|
response=response,
|
||||||
|
text=self.test_workflow_transition_field.label,
|
||||||
|
status_code=200
|
||||||
|
)
|
||||||
|
|
||||||
|
def _request_workflow_transition_field_create_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='document_states:setup_workflow_transition_field_create',
|
||||||
|
kwargs={'pk': self.test_workflow_transition.pk},
|
||||||
|
data={
|
||||||
|
'name': TEST_WORKFLOW_TRANSITION_FIELD_NAME,
|
||||||
|
'label': TEST_WORKFLOW_TRANSITION_FIELD_LABEL,
|
||||||
|
'help_text': TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_create_view_no_permission(self):
|
||||||
|
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||||
|
|
||||||
|
response = self._request_workflow_transition_field_create_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.test_workflow_transition.fields.count(),
|
||||||
|
workflow_transition_field_count
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_create_view_with_access(self):
|
||||||
|
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_workflow, permission=permission_workflow_edit
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_workflow_transition_field_create_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.test_workflow_transition.fields.count(),
|
||||||
|
workflow_transition_field_count + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def _request_workflow_transition_field_delete_view(self):
|
||||||
|
return self.post(
|
||||||
|
viewname='document_states:setup_workflow_transition_field_delete',
|
||||||
|
kwargs={'pk': self.test_workflow_transition_field.pk},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_delete_view_no_permission(self):
|
||||||
|
self._create_test_workflow_transition_field()
|
||||||
|
|
||||||
|
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||||
|
|
||||||
|
response = self._request_workflow_transition_field_delete_view()
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.test_workflow_transition.fields.count(),
|
||||||
|
workflow_transition_field_count
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_workflow_transition_field_delete_view_with_access(self):
|
||||||
|
self._create_test_workflow_transition_field()
|
||||||
|
|
||||||
|
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||||
|
|
||||||
|
self.grant_access(
|
||||||
|
obj=self.test_workflow, permission=permission_workflow_edit
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self._request_workflow_transition_field_delete_view()
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.test_workflow_transition.fields.count(),
|
||||||
|
workflow_transition_field_count - 1
|
||||||
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from django.contrib import messages
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from mayan.apps.acls.models import AccessControlList
|
from mayan.apps.acls.models import AccessControlList
|
||||||
@@ -16,6 +16,7 @@ from mayan.apps.documents.models import Document
|
|||||||
from ..forms import WorkflowInstanceTransitionSelectForm
|
from ..forms import WorkflowInstanceTransitionSelectForm
|
||||||
from ..icons import icon_workflow_instance_detail, icon_workflow_list
|
from ..icons import icon_workflow_instance_detail, icon_workflow_list
|
||||||
from ..links import link_workflow_instance_transition
|
from ..links import link_workflow_instance_transition
|
||||||
|
from ..literals import FIELD_TYPE_MAPPING
|
||||||
from ..models import WorkflowInstance
|
from ..models import WorkflowInstance
|
||||||
from ..permissions import permission_workflow_view
|
from ..permissions import permission_workflow_view
|
||||||
|
|
||||||
@@ -165,7 +166,7 @@ class WorkflowInstanceTransitionExecuteView(FormView):
|
|||||||
for field in self.get_workflow_transition().fields.all():
|
for field in self.get_workflow_transition().fields.all():
|
||||||
schema['fields'][field.name] = {
|
schema['fields'][field.name] = {
|
||||||
'label': field.label,
|
'label': field.label,
|
||||||
'class': 'django.forms.CharField', 'kwargs': {
|
'class': FIELD_TYPE_MAPPING[field.field_type], 'kwargs': {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +220,3 @@ class WorkflowInstanceTransitionSelectView(ExternalObjectMixin, FormView):
|
|||||||
'user': self.request.user,
|
'user': self.request.user,
|
||||||
'workflow_instance': self.external_object
|
'workflow_instance': self.external_object
|
||||||
}
|
}
|
||||||
|
|
||||||
#def get_workflow_instance(self):
|
|
||||||
# return get_object_or_404(klass=WorkflowInstance, pk=self.kwargs['pk'])
|
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ from ..forms import (
|
|||||||
)
|
)
|
||||||
from ..icons import (
|
from ..icons import (
|
||||||
icon_workflow_list, icon_workflow_state, icon_workflow_state_action,
|
icon_workflow_list, icon_workflow_state, icon_workflow_state_action,
|
||||||
icon_workflow_transition
|
icon_workflow_transition, icon_workflow_transition_field
|
||||||
)
|
)
|
||||||
from ..links import (
|
from ..links import (
|
||||||
link_setup_workflow_create, link_setup_workflow_state_create,
|
link_setup_workflow_create, link_setup_workflow_state_create,
|
||||||
link_setup_workflow_state_action_selection,
|
link_setup_workflow_state_action_selection,
|
||||||
link_setup_workflow_transition_create
|
link_setup_workflow_transition_create,
|
||||||
|
link_setup_workflow_transition_field_create,
|
||||||
)
|
)
|
||||||
from ..models import (
|
from ..models import (
|
||||||
Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition,
|
Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition,
|
||||||
@@ -738,8 +739,7 @@ class SetupWorkflowTransitionTriggerEventListView(ExternalObjectMixin, FormView)
|
|||||||
class SetupWorkflowTransitionFieldCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
class SetupWorkflowTransitionFieldCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
||||||
external_object_class = WorkflowTransition
|
external_object_class = WorkflowTransition
|
||||||
external_object_permission = permission_workflow_edit
|
external_object_permission = permission_workflow_edit
|
||||||
fields = ('name', 'label', 'help_text', 'required')
|
fields = ('name', 'label', 'field_type', 'help_text', 'required')
|
||||||
#object_permission = permission_workflow_edit
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
@@ -789,7 +789,7 @@ class SetupWorkflowTransitionFieldDeleteView(SingleObjectDeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class SetupWorkflowTransitionFieldEditView(SingleObjectEditView):
|
class SetupWorkflowTransitionFieldEditView(SingleObjectEditView):
|
||||||
fields = ('name', 'label', 'help_text', 'required',)
|
fields = ('name', 'label', 'field_type', 'help_text', 'required',)
|
||||||
model = WorkflowTransitionField
|
model = WorkflowTransitionField
|
||||||
object_permission = permission_workflow_edit
|
object_permission = permission_workflow_edit
|
||||||
|
|
||||||
@@ -819,21 +819,23 @@ class SetupWorkflowTransitionFieldListView(ExternalObjectMixin, SingleObjectList
|
|||||||
return {
|
return {
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'navigation_object_list': ('object', 'workflow'),
|
'navigation_object_list': ('object', 'workflow'),
|
||||||
#'no_results_icon': icon_workflow_transition_action,
|
'no_results_icon': icon_workflow_transition_field,
|
||||||
#'no_results_main_link': link_setup_workflow_transition_action_selection.resolve(
|
'no_results_main_link': link_setup_workflow_transition_field_create.resolve(
|
||||||
# context=RequestContext(
|
context=RequestContext(
|
||||||
# request=self.request, dict_={
|
request=self.request, dict_={
|
||||||
# 'object': self.get_workflow_transition()
|
'object': self.external_object
|
||||||
# }
|
}
|
||||||
# )
|
)
|
||||||
#),
|
),
|
||||||
#'no_results_text': _(
|
'no_results_text': _(
|
||||||
# 'Workflow state actions are macros that get executed when '
|
'Workflow transition fields allow adding data to the '
|
||||||
# 'documents enters or leaves the state in which they reside.'
|
'workflow\'s context. This additional context data can then '
|
||||||
#),
|
'be used by other elements of the workflow system like the '
|
||||||
#'no_results_title': _(
|
'workflow state actions.'
|
||||||
# 'There are no actions for this workflow state'
|
),
|
||||||
#),
|
'no_results_title': _(
|
||||||
|
'There are no fields for this workflow transition'
|
||||||
|
),
|
||||||
'object': self.external_object,
|
'object': self.external_object,
|
||||||
'title': _(
|
'title': _(
|
||||||
'Fields for workflow transition: %s'
|
'Fields for workflow transition: %s'
|
||||||
|
|||||||
Reference in New Issue
Block a user