Files
mayan-edms/mayan/apps/document_states/serializers.py
Roberto Rosario 8e69178e07 Project: Switch to full app paths
Instead of inserting the path of the apps into the Python app,
the apps are now referenced by their full import path.

This app name claves with external or native Python libraries.
Example: Mayan statistics app vs. Python new statistics library.

Every app reference is now prepended with 'mayan.apps'.

Existing config.yml files need to be updated manually.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
2018-12-05 02:04:20 -04:00

363 lines
12 KiB
Python

from __future__ import unicode_literals
from django.core.exceptions import ValidationError as DjangoValidationError
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.reverse import reverse
from mayan.apps.documents.models import DocumentType
from mayan.apps.documents.serializers import DocumentTypeSerializer
from mayan.apps.user_management.serializers import UserSerializer
from .models import (
Workflow, WorkflowInstance, WorkflowInstanceLogEntry, WorkflowState,
WorkflowTransition
)
class NewWorkflowDocumentTypeSerializer(serializers.Serializer):
document_type_pk = serializers.IntegerField(
help_text=_('Primary key of the document type to be added.')
)
def create(self, validated_data):
document_type = DocumentType.objects.get(
pk=validated_data['document_type_pk']
)
self.context['workflow'].document_types.add(document_type)
return validated_data
class WorkflowDocumentTypeSerializer(DocumentTypeSerializer):
workflow_document_type_url = serializers.SerializerMethodField(
help_text=_(
'API URL pointing to a document type in relation to the '
'workflow to which it is attached. This URL is different than '
'the canonical document type URL.'
)
)
class Meta(DocumentTypeSerializer.Meta):
fields = DocumentTypeSerializer.Meta.fields + (
'workflow_document_type_url',
)
read_only_fields = DocumentTypeSerializer.Meta.fields
def get_workflow_document_type_url(self, instance):
return reverse(
'rest_api:workflow-document-type-detail', args=(
self.context['workflow'].pk, instance.pk
), request=self.context['request'], format=self.context['format']
)
class WorkflowStateSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField()
workflow_url = serializers.SerializerMethodField()
class Meta:
fields = (
'completion', 'id', 'initial', 'label', 'url', 'workflow_url',
)
model = WorkflowState
def create(self, validated_data):
validated_data['workflow'] = self.context['workflow']
return super(WorkflowStateSerializer, self).create(validated_data)
def get_url(self, instance):
return reverse(
'rest_api:workflowstate-detail', args=(
instance.workflow.pk, instance.pk
), request=self.context['request'], format=self.context['format']
)
def get_workflow_url(self, instance):
return reverse(
'rest_api:workflow-detail', args=(
instance.workflow.pk,
), request=self.context['request'], format=self.context['format']
)
class WorkflowTransitionSerializer(serializers.HyperlinkedModelSerializer):
destination_state = WorkflowStateSerializer()
origin_state = WorkflowStateSerializer()
url = serializers.SerializerMethodField()
workflow_url = serializers.SerializerMethodField()
class Meta:
fields = (
'destination_state', 'id', 'label', 'origin_state', 'url',
'workflow_url',
)
model = WorkflowTransition
def get_url(self, instance):
return reverse(
'rest_api:workflowtransition-detail', args=(
instance.workflow.pk, instance.pk
), request=self.context['request'], format=self.context['format']
)
def get_workflow_url(self, instance):
return reverse(
'rest_api:workflow-detail', args=(
instance.workflow.pk,
), request=self.context['request'], format=self.context['format']
)
class WritableWorkflowTransitionSerializer(serializers.ModelSerializer):
destination_state_pk = serializers.IntegerField(
help_text=_('Primary key of the destination state to be added.'),
write_only=True
)
origin_state_pk = serializers.IntegerField(
help_text=_('Primary key of the origin state to be added.'),
write_only=True
)
url = serializers.SerializerMethodField()
workflow_url = serializers.SerializerMethodField()
class Meta:
fields = (
'destination_state_pk', 'id', 'label', 'origin_state_pk', 'url',
'workflow_url',
)
model = WorkflowTransition
def create(self, validated_data):
validated_data['destination_state'] = WorkflowState.objects.get(
pk=validated_data.pop('destination_state_pk')
)
validated_data['origin_state'] = WorkflowState.objects.get(
pk=validated_data.pop('origin_state_pk')
)
validated_data['workflow'] = self.context['workflow']
return super(WritableWorkflowTransitionSerializer, self).create(
validated_data
)
def get_url(self, instance):
return reverse(
'rest_api:workflowtransition-detail', args=(
instance.workflow.pk, instance.pk
), request=self.context['request'], format=self.context['format']
)
def get_workflow_url(self, instance):
return reverse(
'rest_api:workflow-detail', args=(
instance.workflow.pk,
), request=self.context['request'], format=self.context['format']
)
def update(self, instance, validated_data):
validated_data['destination_state'] = WorkflowState.objects.get(
pk=validated_data.pop('destination_state_pk')
)
validated_data['origin_state'] = WorkflowState.objects.get(
pk=validated_data.pop('origin_state_pk')
)
return super(WritableWorkflowTransitionSerializer, self).update(
instance, validated_data
)
class WorkflowSerializer(serializers.HyperlinkedModelSerializer):
document_types_url = serializers.HyperlinkedIdentityField(
view_name='rest_api:workflow-document-type-list'
)
image_url = serializers.SerializerMethodField()
states = WorkflowStateSerializer(many=True, required=False)
transitions = WorkflowTransitionSerializer(many=True, required=False)
class Meta:
extra_kwargs = {
'url': {'view_name': 'rest_api:workflow-detail'},
}
fields = (
'document_types_url', 'image_url', 'id', 'internal_name', 'label',
'states', 'transitions', 'url'
)
model = Workflow
def get_image_url(self, instance):
return reverse(
'rest_api:workflow-image', args=(
instance.pk,
), request=self.context['request'], format=self.context['format']
)
class WorkflowInstanceLogEntrySerializer(serializers.ModelSerializer):
document_workflow_url = serializers.SerializerMethodField()
transition = WorkflowTransitionSerializer(read_only=True)
user = UserSerializer(read_only=True)
class Meta:
fields = (
'comment', 'datetime', 'document_workflow_url', 'transition',
'user'
)
model = WorkflowInstanceLogEntry
def get_document_workflow_url(self, instance):
return reverse(
'rest_api:workflowinstance-detail', args=(
instance.workflow_instance.document.pk,
instance.workflow_instance.pk,
), request=self.context['request'], format=self.context['format']
)
class WorkflowInstanceSerializer(serializers.ModelSerializer):
current_state = WorkflowStateSerializer(
read_only=True, source='get_current_state'
)
document_workflow_url = serializers.SerializerMethodField(
help_text=_(
'API URL pointing to a workflow in relation to the '
'document to which it is attached. This URL is different than '
'the canonical workflow URL.'
)
)
last_log_entry = WorkflowInstanceLogEntrySerializer(
read_only=True, source='get_last_log_entry'
)
log_entries_url = serializers.SerializerMethodField(
help_text=_('A link to the entire history of this workflow.')
)
transition_choices = WorkflowTransitionSerializer(
many=True, read_only=True, source='get_transition_choices'
)
workflow = WorkflowSerializer(read_only=True)
class Meta:
fields = (
'current_state', 'document_workflow_url', 'last_log_entry',
'log_entries_url', 'transition_choices', 'workflow',
)
model = WorkflowInstance
def get_document_workflow_url(self, instance):
return reverse(
'rest_api:workflowinstance-detail', args=(
instance.document.pk, instance.pk,
), request=self.context['request'], format=self.context['format']
)
def get_log_entries_url(self, instance):
return reverse(
'rest_api:workflowinstancelogentry-list', args=(
instance.document.pk, instance.pk,
), request=self.context['request'], format=self.context['format']
)
class WritableWorkflowSerializer(serializers.ModelSerializer):
document_types_pk_list = serializers.CharField(
help_text=_(
'Comma separated list of document type primary keys to which this '
'workflow will be attached.'
), required=False
)
class Meta:
extra_kwargs = {
'url': {'view_name': 'rest_api:workflow-detail'},
}
fields = (
'document_types_pk_list', 'label', 'id', 'url',
)
model = Workflow
def _add_document_types(self, document_types_pk_list, instance):
instance.document_types.add(
*DocumentType.objects.filter(
pk__in=document_types_pk_list.split(',')
)
)
def create(self, validated_data):
document_types_pk_list = validated_data.pop(
'document_types_pk_list', ''
)
instance = super(WritableWorkflowSerializer, self).create(
validated_data
)
if document_types_pk_list:
self._add_document_types(
document_types_pk_list=document_types_pk_list,
instance=instance
)
return instance
def update(self, instance, validated_data):
document_types_pk_list = validated_data.pop(
'document_types_pk_list', ''
)
instance = super(WritableWorkflowSerializer, self).update(
instance, validated_data
)
if document_types_pk_list:
instance.documents.clear()
self._add_documents(
document_types_pk_list=document_types_pk_list,
instance=instance
)
return instance
class WritableWorkflowInstanceLogEntrySerializer(serializers.ModelSerializer):
document_workflow_url = serializers.SerializerMethodField()
transition_pk = serializers.IntegerField(
help_text=_('Primary key of the transition to be added.'),
write_only=True
)
transition = WorkflowTransitionSerializer(read_only=True)
user = UserSerializer(read_only=True)
class Meta:
fields = (
'comment', 'datetime', 'document_workflow_url', 'transition',
'transition_pk', 'user'
)
model = WorkflowInstanceLogEntry
def get_document_workflow_url(self, instance):
return reverse(
'rest_api:workflowinstance-detail', args=(
instance.workflow_instance.document.pk,
instance.workflow_instance.pk,
), request=self.context['request'], format=self.context['format']
)
def validate(self, attrs):
attrs['user'] = self.context['request'].user
attrs['workflow_instance'] = self.context['workflow_instance']
attrs['transition'] = WorkflowTransition.objects.get(
pk=attrs.pop('transition_pk')
)
instance = WorkflowInstanceLogEntry(**attrs)
try:
instance.full_clean()
except DjangoValidationError as exception:
raise ValidationError(exception)
return attrs