diff --git a/HISTORY.rst b/HISTORY.rst index c44e47e139..549d023641 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -166,6 +166,7 @@ - Add support for setting migrations. - Add setting migrations for the common, converter, documents, file metadata, and document signatures app. +- Add document type change API endpoint. 3.2.10 (2019-XX-XX) =================== diff --git a/mayan/apps/documents/api_views.py b/mayan/apps/documents/api_views.py index 2b79d8fb61..f8ceb5eee9 100644 --- a/mayan/apps/documents/api_views.py +++ b/mayan/apps/documents/api_views.py @@ -30,9 +30,10 @@ from .permissions import ( from .serializers import ( DeletedDocumentSerializer, DocumentPageSerializer, DocumentSerializer, DocumentTypeSerializer, DocumentVersionSerializer, - NewDocumentSerializer, NewDocumentVersionSerializer, - RecentDocumentSerializer, WritableDocumentSerializer, - WritableDocumentTypeSerializer, WritableDocumentVersionSerializer + NewDocumentDocumentTypeSerializer, NewDocumentSerializer, + NewDocumentVersionSerializer, RecentDocumentSerializer, + WritableDocumentSerializer, WritableDocumentTypeSerializer, + WritableDocumentVersionSerializer ) from .settings import settings_document_page_image_cache_time from .tasks import task_generate_document_page_image @@ -83,6 +84,26 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView): return Response(status=status.HTTP_200_OK) +class APIDocumentDocumentTypeChangeView(generics.GenericAPIView): + """ + post: Change the type of the selected document. + """ + mayan_object_permissions = { + 'POST': (permission_document_properties_edit,), + } + queryset = Document.objects.all() + serializer_class = NewDocumentDocumentTypeSerializer + + def post(self, request, *args, **kwargs): + serializer = self.get_serializer(data=request.data) + serializer.is_valid(raise_exception=True) + document_type = DocumentType.objects.get(pk=request.data['new_document_type']) + self.get_object().set_document_type( + document_type=document_type, _user=self.request.user + ) + return Response(status=status.HTTP_200_OK) + + class APIDocumentDownloadView(DownloadMixin, generics.RetrieveAPIView): """ get: Download the latest version of a document. diff --git a/mayan/apps/documents/serializers.py b/mayan/apps/documents/serializers.py index 9632a546cb..873b573886 100644 --- a/mayan/apps/documents/serializers.py +++ b/mayan/apps/documents/serializers.py @@ -237,7 +237,10 @@ class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer): class DocumentSerializer(serializers.HyperlinkedModelSerializer): - document_type = DocumentTypeSerializer() + document_type = DocumentTypeSerializer(read_only=True) + document_type_change_url = serializers.HyperlinkedIdentityField( + view_name='rest_api:document-type-change', + ) latest_version = DocumentVersionSerializer(many=False, read_only=True) versions_url = serializers.HyperlinkedIdentityField( view_name='rest_api:document-version-list', @@ -246,16 +249,27 @@ class DocumentSerializer(serializers.HyperlinkedModelSerializer): class Meta: extra_kwargs = { 'document_type': {'view_name': 'rest_api:documenttype-detail'}, - 'url': {'view_name': 'rest_api:document-detail'} + 'url': {'view_name': 'rest_api:document-detail'}, } fields = ( - 'date_added', 'description', 'document_type', 'id', 'label', - 'language', 'latest_version', 'url', 'uuid', 'versions_url', + 'date_added', 'description', 'document_type', + 'document_type_change_url', 'id', 'label', 'language', + 'latest_version', 'url', 'uuid', 'pk', 'versions_url', ) model = Document read_only_fields = ('document_type',) +class NewDocumentDocumentTypeSerializer(serializers.ModelSerializer): + new_document_type = serializers.PrimaryKeyRelatedField( + queryset=DocumentType.objects.all(), write_only=True + ) + + class Meta: + fields = ('new_document_type',) + model = Document + + class WritableDocumentSerializer(serializers.ModelSerializer): document_type = DocumentTypeSerializer(read_only=True) latest_version = DocumentVersionSerializer(many=False, read_only=True) diff --git a/mayan/apps/documents/tests/test_api.py b/mayan/apps/documents/tests/test_api.py index e4dfae6daa..a7fca309af 100644 --- a/mayan/apps/documents/tests/test_api.py +++ b/mayan/apps/documents/tests/test_api.py @@ -22,7 +22,7 @@ from ..permissions import ( from .literals import ( TEST_DOCUMENT_DESCRIPTION_EDITED, TEST_PDF_DOCUMENT_FILENAME, - TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE_LABEL, + TEST_DOCUMENT_PATH, TEST_DOCUMENT_TYPE_LABEL, TEST_DOCUMENT_TYPE_2_LABEL, TEST_DOCUMENT_TYPE_LABEL_EDITED, TEST_DOCUMENT_VERSION_COMMENT_EDITED, TEST_SMALL_DOCUMENT_FILENAME ) @@ -184,6 +184,13 @@ class DocumentAPIViewTestMixin(object): }, data={'description': TEST_DOCUMENT_DESCRIPTION_EDITED} ) + def _request_test_document_document_type_change_api_view(self): + return self.post( + viewname='rest_api:document-type-change', kwargs={ + 'pk': self.test_document.pk + }, data={'new_document_type': self.test_document_type_2.pk} + ) + class DocumentAPIViewTestCase( DocumentAPIViewTestMixin, DocumentTestMixin, BaseAPITestCase @@ -254,6 +261,40 @@ class DocumentAPIViewTestCase( ) self.assertEqual(document.page_count, 47) + def test_document_document_type_change_api_via_no_permission(self): + self.upload_document() + self.test_document_type_2 = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE_2_LABEL + ) + + response = self._request_test_document_document_type_change_api_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + self.test_document.refresh_from_db() + self.assertEqual( + self.test_document.document_type, + self.test_document_type + ) + + def test_document_document_type_change_api_via_with_access(self): + self.upload_document() + self.grant_access( + obj=self.test_document, + permission=permission_document_properties_edit + ) + self.test_document_type_2 = DocumentType.objects.create( + label=TEST_DOCUMENT_TYPE_2_LABEL + ) + + response = self._request_test_document_document_type_change_api_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.test_document.refresh_from_db() + self.assertEqual( + self.test_document.document_type, + self.test_document_type_2 + ) + def test_document_description_api_edit_via_patch_view_no_permission(self): self.upload_document() diff --git a/mayan/apps/documents/urls.py b/mayan/apps/documents/urls.py index 64640f12f2..6be733e983 100644 --- a/mayan/apps/documents/urls.py +++ b/mayan/apps/documents/urls.py @@ -4,13 +4,13 @@ from django.conf.urls import url from .api_views import ( APITrashedDocumentListView, APIDeletedDocumentRestoreView, - APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentView, - APIDocumentListView, APIDocumentVersionDownloadView, - APIDocumentPageImageView, APIDocumentPageView, - APIDocumentTypeDocumentListView, APIDocumentTypeListView, - APIDocumentTypeView, APIDocumentVersionsListView, - APIDocumentVersionPageListView, APIDocumentVersionView, - APIRecentDocumentListView + APIDeletedDocumentView, APIDocumentDocumentTypeChangeView, + APIDocumentDownloadView, APIDocumentView, APIDocumentListView, + APIDocumentVersionDownloadView, APIDocumentPageImageView, + APIDocumentPageView, APIDocumentTypeDocumentListView, + APIDocumentTypeListView, APIDocumentTypeView, + APIDocumentVersionsListView, APIDocumentVersionPageListView, + APIDocumentVersionView, APIRecentDocumentListView ) from .views.document_page_views import ( DocumentPageDisable, DocumentPageEnable, DocumentPageListView, @@ -393,6 +393,11 @@ api_urls = [ regex=r'^documents/(?P[0-9]+)/download/$', view=APIDocumentDownloadView.as_view(), name='document-download' ), + url( + regex=r'^documents/(?P[0-9]+)/type/change/$', + view=APIDocumentDocumentTypeChangeView.as_view(), + name='document-type-change' + ), url( regex=r'^documents/(?P[0-9]+)/versions/$', view=APIDocumentVersionsListView.as_view(),