diff --git a/mayan/apps/documents/admin.py b/mayan/apps/documents/admin.py index d4f6671d9e..d473d8f4b3 100644 --- a/mayan/apps/documents/admin.py +++ b/mayan/apps/documents/admin.py @@ -3,8 +3,8 @@ from __future__ import unicode_literals from django.contrib import admin from .models import ( - DeletedDocument, Document, DocumentPage, DocumentType, - DocumentTypeFilename, DocumentVersion, RecentDocument + Document, DocumentPage, DocumentType, DocumentTypeFilename, + DocumentVersion, RecentDocument, TrashedDocument ) @@ -29,14 +29,6 @@ class DocumentVersionInline(admin.StackedInline): allow_add = True -@admin.register(DeletedDocument) -class DeletedDocumentAdmin(admin.ModelAdmin): - date_hierarchy = 'deleted_date_time' - list_filter = ('document_type',) - list_display = ('uuid', 'label', 'document_type', 'deleted_date_time') - readonly_fields = ('uuid', 'document_type') - - @admin.register(Document) class DocumentAdmin(admin.ModelAdmin): date_hierarchy = 'date_added' @@ -62,3 +54,11 @@ class RecentDocumentAdmin(admin.ModelAdmin): list_display_links = ('document', 'datetime_accessed') list_filter = ('user',) readonly_fields = ('user', 'document', 'datetime_accessed') + + +@admin.register(TrashedDocument) +class TrashedDocumentAdmin(admin.ModelAdmin): + date_hierarchy = 'deleted_date_time' + list_filter = ('document_type',) + list_display = ('uuid', 'label', 'document_type', 'deleted_date_time') + readonly_fields = ('uuid', 'document_type') diff --git a/mayan/apps/documents/api_views.py b/mayan/apps/documents/api_views.py index c33ecfd8e7..644c804f22 100644 --- a/mayan/apps/documents/api_views.py +++ b/mayan/apps/documents/api_views.py @@ -27,7 +27,7 @@ from .permissions import ( permission_document_type_edit, permission_document_type_view ) from .serializers import ( - DeletedDocumentSerializer, DocumentPageImageSerializer, + TrashedDocumentSerializer, DocumentPageImageSerializer, DocumentPageSerializer, DocumentSerializer, DocumentTypeSerializer, DocumentVersionSerializer, DocumentVersionRevertSerializer, NewDocumentSerializer, @@ -37,7 +37,7 @@ from .serializers import ( logger = logging.getLogger(__name__) -class APIDeletedDocumentListView(generics.ListAPIView): +class APITrashedDocumentListView(generics.ListAPIView): """ Returns a list of all the trashed documents. """ @@ -46,10 +46,10 @@ class APIDeletedDocumentListView(generics.ListAPIView): mayan_object_permissions = {'GET': (permission_document_view,)} permission_classes = (MayanPermission,) queryset = Document.trash.all() - serializer_class = DeletedDocumentSerializer + serializer_class = TrashedDocumentSerializer -class APIDeletedDocumentView(generics.RetrieveDestroyAPIView): +class APITrashedDocumentView(generics.RetrieveDestroyAPIView): """ Returns the selected trashed document details. """ @@ -59,17 +59,17 @@ class APIDeletedDocumentView(generics.RetrieveDestroyAPIView): } permission_classes = (MayanPermission,) queryset = Document.trash.all() - serializer_class = DeletedDocumentSerializer + serializer_class = TrashedDocumentSerializer def delete(self, *args, **kwargs): """ Delete the trashed document. """ - return super(APIDeletedDocumentView, self).delete(*args, **kwargs) + return super(APITrashedDocumentView, self).delete(*args, **kwargs) -class APIDeletedDocumentRestoreView(generics.GenericAPIView): +class APITrashedDocumentRestoreView(generics.GenericAPIView): """ Restore a trashed document. """ @@ -80,7 +80,7 @@ class APIDeletedDocumentRestoreView(generics.GenericAPIView): permission_classes = (MayanPermission,) queryset = Document.trash.all() - serializer_class = DeletedDocumentSerializer + serializer_class = TrashedDocumentSerializer def post(self, *args, **kwargs): self.get_object().restore() diff --git a/mayan/apps/documents/apps.py b/mayan/apps/documents/apps.py index 1abfd005e5..2d4c6abda5 100644 --- a/mayan/apps/documents/apps.py +++ b/mayan/apps/documents/apps.py @@ -36,7 +36,7 @@ from .links import ( link_clear_image_cache, link_document_clear_transformations, link_document_delete, link_document_document_type_edit, link_document_multiple_document_type_edit, link_document_download, - link_document_edit, link_document_list, link_document_list_deleted, + link_document_edit, link_document_list, link_document_list_trashed, link_document_list_recent, link_document_multiple_delete, link_document_multiple_trash, link_document_multiple_clear_transformations, link_document_multiple_download, link_document_multiple_restore, @@ -87,12 +87,12 @@ class DocumentsApp(MayanAppConfig): APIEndPoint(app=self, version_string='1') - DeletedDocument = self.get_model('DeletedDocument') Document = self.get_model('Document') DocumentPage = self.get_model('DocumentPage') DocumentType = self.get_model('DocumentType') DocumentTypeFilename = self.get_model('DocumentTypeFilename') DocumentVersion = self.get_model('DocumentVersion') + TrashedDocument = self.get_model('TrashedDocument') MissingItem( label=_('Create a document type'), @@ -172,20 +172,20 @@ class DocumentsApp(MayanAppConfig): ) SourceColumn( - source=DeletedDocument, label=_('Thumbnail'), + source=TrashedDocument, label=_('Thumbnail'), func=lambda context: document_thumbnail( context['object'], - gallery_name='documents:delete_document_list', + gallery_name='documents:trashed_document_list', size=setting_thumbnail_size.value, title=getattr(context['object'], 'label', None), disable_title_link=True ) ) SourceColumn( - source=DeletedDocument, label=_('Type'), attribute='document_type' + source=TrashedDocument, label=_('Type'), attribute='document_type' ) SourceColumn( - source=DeletedDocument, label=_('Date time trashed'), + source=TrashedDocument, label=_('Date time trashed'), attribute='deleted_date_time' ) @@ -268,7 +268,7 @@ class DocumentsApp(MayanAppConfig): menu_front_page.bind_links( links=( link_document_list_recent, link_document_list, - link_document_list_deleted + link_document_list_trashed ) ) menu_setup.bind_links(links=(link_document_type_setup,)) @@ -304,7 +304,7 @@ class DocumentsApp(MayanAppConfig): menu_sidebar.bind_links( links=(link_trash_can_empty,), sources=( - 'documents:document_list_deleted', 'documents:trash_can_empty' + 'documents:document_list_trashed', 'documents:trash_can_empty' ) ) @@ -319,7 +319,7 @@ class DocumentsApp(MayanAppConfig): ) menu_object.bind_links( links=(link_document_restore, link_document_delete), - sources=(DeletedDocument,) + sources=(TrashedDocument,) ) # Document facet links @@ -354,7 +354,7 @@ class DocumentsApp(MayanAppConfig): menu_multi_item.bind_links( links=( link_document_multiple_restore, link_document_multiple_delete - ), sources=(DeletedDocument,) + ), sources=(TrashedDocument,) ) # Document pages @@ -430,5 +430,5 @@ class DocumentsApp(MayanAppConfig): dispatch_uid='create_default_document_type' ) - registry.register(DeletedDocument) + registry.register(TrashedDocument) registry.register(Document) diff --git a/mayan/apps/documents/links.py b/mayan/apps/documents/links.py index 6b64e5fb2b..bfe617be39 100644 --- a/mayan/apps/documents/links.py +++ b/mayan/apps/documents/links.py @@ -140,9 +140,9 @@ link_document_list_recent = Link( icon='fa fa-clock-o', text=_('Recent documents'), view='documents:document_list_recent' ) -link_document_list_deleted = Link( +link_document_list_trashed = Link( icon='fa fa-trash', text=_('Trash'), - view='documents:document_list_deleted' + view='documents:document_list_trashed' ) # Tools diff --git a/mayan/apps/documents/managers.py b/mayan/apps/documents/managers.py index 40bfbb836c..73c7097e42 100644 --- a/mayan/apps/documents/managers.py +++ b/mayan/apps/documents/managers.py @@ -23,9 +23,9 @@ class DocumentManager(models.Manager): return self.get(uuid=uuid) def get_queryset(self): - return TrashCanQuerySet( + return TrashedDocumentQuerySet( self.model, using=self._db - ).filter(in_trash=False) + ) def invalidate_cache(self): for document in self.model.objects.all(): @@ -50,7 +50,7 @@ class DocumentTypeManager(models.Manager): 'Document type: %s, has a deletion period delta of: %s', document_type, delta ) - for document in document_type.deleted_documents.filter(deleted_date_time__lt=now() - delta): + for document in document_type.trashed_documents.filter(deleted_date_time__lt=now() - delta): logger.info( 'Document "%s" with id: %d, trashed on: %s, exceded ' 'delete period', document, document.pk, @@ -110,8 +110,26 @@ class NewVersionBlockManager(models.Manager): return self.filter(document=document).exists() -class PassthroughManager(models.Manager): - pass +class OrganizationDocumentManager(models.Manager): + def get_queryset(self): + DocumentType = apps.get_model('documents', 'DocumentType') + + return TrashedDocumentQuerySet( + self.model, using=self._db + ).filter(in_trash=False).filter( + document_type__in=DocumentType.on_organization.all() + ) + + +class OrganizationDocumentVersionManager(models.Manager): + def get_queryset(self): + DocumentType = apps.get_model('documents', 'DocumentType') + + return super( + OrganizationDocumentVersionManager, self + ).get_queryset().filter( + document__document_type__in=DocumentType.on_organization.all() + ) class RecentDocumentManager(models.Manager): @@ -130,25 +148,28 @@ class RecentDocumentManager(models.Manager): return new_recent def get_for_user(self, user): - document_model = apps.get_model('documents', 'document') + Document = apps.get_model('documents', 'Document') if user.is_authenticated(): - return document_model.objects.filter( + return Document.objects.filter( recentdocument__user=user, - document_type__organization__id=settings.ORGANIZATION_ID ).order_by('-recentdocument__datetime_accessed') else: return document_model.objects.none() -class TrashCanManager(models.Manager): +class TrashedDocumentManager(models.Manager): def get_queryset(self): + DocumentType = apps.get_model('documents', 'DocumentType') + return super( - TrashCanManager, self - ).get_queryset().filter(in_trash=True) + TrashedDocumentManager, self + ).get_queryset().filter(in_trash=True).filter( + document_type__in=DocumentType.on_organization.all() + ) -class TrashCanQuerySet(models.QuerySet): +class TrashedDocumentQuerySet(models.QuerySet): def delete(self, to_trash=True): for instance in self: instance.delete(to_trash=to_trash) diff --git a/mayan/apps/documents/models.py b/mayan/apps/documents/models.py index b8808bf040..e04cc34894 100644 --- a/mayan/apps/documents/models.py +++ b/mayan/apps/documents/models.py @@ -37,7 +37,8 @@ from .exceptions import NewDocumentVersionNotAllowed from .literals import DEFAULT_DELETE_PERIOD, DEFAULT_DELETE_TIME_UNIT from .managers import ( DocumentManager, DocumentTypeManager, NewVersionBlockManager, - PassthroughManager, RecentDocumentManager, TrashCanManager + OrganizationDocumentManager, OrganizationDocumentVersionManager, + RecentDocumentManager, TrashedDocumentManager ) from .permissions import permission_document_view from .runtime import cache_storage_backend, storage_backend @@ -99,7 +100,7 @@ class DocumentType(models.Model): return self.label def delete(self, *args, **kwargs): - for document in Document.passthrough.filter(document_type=self): + for document in Document.objects.filter(document_type=self): document.delete(to_trash=False) return super(DocumentType, self).delete(*args, **kwargs) @@ -113,8 +114,8 @@ class DocumentType(models.Model): verbose_name_plural = _('Documents types') @property - def deleted_documents(self): - return DeletedDocument.objects.filter(document_type=self) + def trashed_documents(self): + return TrashedDocument.objects.filter(document_type=self) def get_document_count(self, user): queryset = self.documents @@ -192,9 +193,14 @@ class Document(models.Model): ), verbose_name=_('Is stub?') ) + # objects manager needs to go first otherwise + # objects becomes equal to ActiveDocumentManager(), which it shouldn't. + # The first manager becomes the default manager. + # https://docs.djangoproject.com/en/1.9/topics/db/managers/#default-managers + objects = DocumentManager() - passthrough = PassthroughManager() - trash = TrashCanManager() + on_organization = OrganizationDocumentManager() + trash = TrashedDocumentManager() def __str__(self): return self.label or ugettext('Document stub, id: %d') % self.pk @@ -331,8 +337,8 @@ class Document(models.Model): return 0 -class DeletedDocument(Document): - objects = TrashCanManager() +class TrashedDocument(Document): + objects = TrashedDocumentManager() class Meta: proxy = True @@ -379,6 +385,9 @@ class DocumentVersion(models.Model): blank=True, editable=False, null=True, verbose_name=_('Checksum') ) + objects = models.Manager() + on_organization = OrganizationDocumentVersionManager() + def __str__(self): return '{0} - {1}'.format(self.document, self.timestamp) diff --git a/mayan/apps/documents/serializers.py b/mayan/apps/documents/serializers.py index 8a07cb12d4..bf6294944c 100644 --- a/mayan/apps/documents/serializers.py +++ b/mayan/apps/documents/serializers.py @@ -103,32 +103,6 @@ class NewDocumentVersionSerializer(serializers.Serializer): ) -class DeletedDocumentSerializer(serializers.HyperlinkedModelSerializer): - document_type_label = serializers.SerializerMethodField() - restore = serializers.HyperlinkedIdentityField( - view_name='rest_api:deleteddocument-restore' - ) - - def get_document_type_label(self, instance): - return instance.document_type.label - - class Meta: - extra_kwargs = { - 'document_type': {'view_name': 'rest_api:documenttype-detail'}, - 'url': {'view_name': 'rest_api:deleteddocument-detail'} - } - fields = ( - 'date_added', 'deleted_date_time', 'description', 'document_type', - 'document_type_label', 'id', 'label', 'language', 'restore', - 'url', 'uuid', - ) - model = Document - read_only_fields = ( - 'deleted_date_time', 'description', 'document_type', 'label', - 'language' - ) - - class DocumentSerializer(serializers.HyperlinkedModelSerializer): document_type_label = serializers.SerializerMethodField() latest_version = DocumentVersionSerializer(many=False, read_only=True) @@ -191,3 +165,29 @@ class RecentDocumentSerializer(serializers.ModelSerializer): class Meta: fields = ('document', 'datetime_accessed') model = RecentDocument + + +class TrashedDocumentSerializer(serializers.HyperlinkedModelSerializer): + document_type_label = serializers.SerializerMethodField() + restore = serializers.HyperlinkedIdentityField( + view_name='rest_api:deleteddocument-restore' + ) + + def get_document_type_label(self, instance): + return instance.document_type.label + + class Meta: + extra_kwargs = { + 'document_type': {'view_name': 'rest_api:documenttype-detail'}, + 'url': {'view_name': 'rest_api:deleteddocument-detail'} + } + fields = ( + 'date_added', 'deleted_date_time', 'description', 'document_type', + 'document_type_label', 'id', 'label', 'language', 'restore', + 'url', 'uuid', + ) + model = Document + read_only_fields = ( + 'deleted_date_time', 'description', 'document_type', 'label', + 'language' + ) diff --git a/mayan/apps/documents/tests/test_api.py b/mayan/apps/documents/tests/test_api.py index 579104e5a8..ce7fadc6aa 100644 --- a/mayan/apps/documents/tests/test_api.py +++ b/mayan/apps/documents/tests/test_api.py @@ -15,6 +15,7 @@ from django.utils.six import BytesIO from rest_framework import status from rest_framework.test import APITestCase +from organizations.utils import create_default_organization from user_management.tests.literals import ( TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME ) @@ -32,7 +33,9 @@ class DocumentTypeAPITestCase(APITestCase): """ def setUp(self): - self.admin_user = get_user_model().objects.create_superuser( + create_default_organization() + + self.admin_user = get_user_model().create_superuser( username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, password=TEST_ADMIN_PASSWORD ) @@ -45,7 +48,7 @@ class DocumentTypeAPITestCase(APITestCase): self.admin_user.delete() def test_document_type_create(self): - self.assertEqual(DocumentType.objects.all().count(), 0) + self.assertEqual(DocumentType.on_organization.all().count(), 0) self.client.post( reverse('rest_api:documenttype-list'), data={ @@ -53,41 +56,47 @@ class DocumentTypeAPITestCase(APITestCase): } ) - self.assertEqual(DocumentType.objects.all().count(), 1) + self.assertEqual(DocumentType.on_organization.all().count(), 1) self.assertEqual( DocumentType.objects.all().first().label, TEST_DOCUMENT_TYPE ) def test_document_type_edit_via_put(self): - document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE) + document_type = DocumentType.on_organization.create( + label=TEST_DOCUMENT_TYPE + ) self.client.put( reverse('rest_api:documenttype-detail', args=(document_type.pk,)), {'label': TEST_DOCUMENT_TYPE + 'edited'} ) - document_type = DocumentType.objects.get(pk=document_type.pk) + document_type = DocumentType.on_organization.get(pk=document_type.pk) self.assertEqual(document_type.label, TEST_DOCUMENT_TYPE + 'edited') def test_document_type_edit_via_patch(self): - document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE) + document_type = DocumentType.on_organization.create( + label=TEST_DOCUMENT_TYPE + ) self.client.patch( reverse('rest_api:documenttype-detail', args=(document_type.pk,)), {'label': TEST_DOCUMENT_TYPE + 'edited'} ) - document_type = DocumentType.objects.get(pk=document_type.pk) + document_type = DocumentType.on_organization.get(pk=document_type.pk) self.assertEqual(document_type.label, TEST_DOCUMENT_TYPE + 'edited') def test_document_type_delete(self): - document_type = DocumentType.objects.create(label=TEST_DOCUMENT_TYPE) + document_type = DocumentType.on_organization.create( + label=TEST_DOCUMENT_TYPE + ) self.client.delete( reverse('rest_api:documenttype-detail', args=(document_type.pk,)) ) - self.assertEqual(DocumentType.objects.all().count(), 0) + self.assertEqual(DocumentType.on_organization.all().count(), 0) @override_settings(OCR_AUTO_OCR=False) @@ -106,7 +115,7 @@ class DocumentAPITestCase(APITestCase): username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD ) - self.document_type = DocumentType.objects.create( + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -128,9 +137,9 @@ class DocumentAPITestCase(APITestCase): self.assertEqual( response.status_code, status.HTTP_201_CREATED ) - self.assertEqual(Document.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 1) - document = Document.objects.first() + document = Document.on_organization.first() self.assertEqual(document.pk, document_data['id']) @@ -158,41 +167,9 @@ class DocumentAPITestCase(APITestCase): reverse('rest_api:document-detail', args=(document.pk,)) ) - self.assertEqual(Document.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 0) self.assertEqual(Document.trash.count(), 1) - def test_deleted_document_delete_from_trash(self): - with open(TEST_SMALL_DOCUMENT_PATH) as file_object: - document = self.document_type.new_document( - file_object=file_object, - ) - - document.delete() - - self.assertEqual(Document.objects.count(), 0) - self.assertEqual(Document.trash.count(), 1) - - self.client.delete( - reverse('rest_api:trasheddocument-detail', args=(document.pk,)) - ) - - self.assertEqual(Document.trash.count(), 0) - - def test_deleted_document_restore(self): - with open(TEST_SMALL_DOCUMENT_PATH) as file_object: - document = self.document_type.new_document( - file_object=file_object, - ) - - document.delete() - - self.client.post( - reverse('rest_api:trasheddocument-restore', args=(document.pk,)) - ) - - self.assertEqual(Document.trash.count(), 0) - self.assertEqual(Document.objects.count(), 1) - def test_document_new_version_upload(self): with open(TEST_SMALL_DOCUMENT_PATH) as file_object: document = self.document_type.new_document( @@ -293,5 +270,34 @@ class DocumentAPITestCase(APITestCase): del(buf) - # TODO: def test_document_set_document_type(self): - # pass + def test_trashed_document_delete_from_trash(self): + with open(TEST_SMALL_DOCUMENT_PATH) as file_object: + document = self.document_type.new_document( + file_object=file_object, + ) + + document.delete() + + self.assertEqual(Document.on_organization.count(), 0) + self.assertEqual(Document.trash.count(), 1) + + self.client.delete( + reverse('rest_api:trasheddocument-detail', args=(document.pk,)) + ) + + self.assertEqual(Document.trash.count(), 0) + + def test_trashed_document_restore(self): + with open(TEST_SMALL_DOCUMENT_PATH) as file_object: + document = self.document_type.new_document( + file_object=file_object, + ) + + document.delete() + + self.client.post( + reverse('rest_api:trasheddocument-restore', args=(document.pk,)) + ) + + self.assertEqual(Document.trash.count(), 0) + self.assertEqual(Document.on_organization.count(), 1) diff --git a/mayan/apps/documents/tests/test_models.py b/mayan/apps/documents/tests/test_models.py index c8ec1d737e..2fce77f470 100644 --- a/mayan/apps/documents/tests/test_models.py +++ b/mayan/apps/documents/tests/test_models.py @@ -5,9 +5,11 @@ import time from django.test import TestCase, override_settings +from organizations.utils import create_default_organization + from ..exceptions import NewDocumentVersionNotAllowed from ..literals import STUB_EXPIRATION_INTERVAL -from ..models import DeletedDocument, Document, DocumentType, NewVersionBlock +from ..models import Document, DocumentType, NewVersionBlock, TrashedDocument from .literals import ( TEST_DOCUMENT_TYPE, TEST_DOCUMENT_PATH, TEST_MULTI_PAGE_TIFF_PATH, @@ -18,7 +20,8 @@ from .literals import ( @override_settings(OCR_AUTO_OCR=False) class DocumentTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -57,30 +60,30 @@ class DocumentTestCase(TestCase): self.assertEqual(self.document.versions.count(), 3) def test_restoring_documents(self): - self.assertEqual(Document.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 1) # Trash the document self.document.delete() - self.assertEqual(DeletedDocument.objects.count(), 1) - self.assertEqual(Document.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 0) # Restore the document self.document.restore() - self.assertEqual(DeletedDocument.objects.count(), 0) - self.assertEqual(Document.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 1) def test_trashing_documents(self): - self.assertEqual(Document.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 1) # Trash the document self.document.delete() - self.assertEqual(DeletedDocument.objects.count(), 1) - self.assertEqual(Document.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 0) # Delete the document self.document.delete() - self.assertEqual(DeletedDocument.objects.count(), 0) - self.assertEqual(Document.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 0) def test_auto_trashing(self): """ @@ -97,13 +100,13 @@ class DocumentTestCase(TestCase): # field time.sleep(2) - self.assertEqual(Document.objects.count(), 1) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 0) DocumentType.objects.check_trash_periods() - self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 1) def test_auto_delete(self): """ @@ -116,13 +119,13 @@ class DocumentTestCase(TestCase): self.document_type.delete_time_unit = 'seconds' self.document_type.save() - self.assertEqual(Document.objects.count(), 1) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 0) self.document.delete() - self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(Document.on_organization.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 1) # Needed by MySQL as milliseconds value is not store in timestamp # field @@ -130,14 +133,15 @@ class DocumentTestCase(TestCase): DocumentType.objects.check_delete_periods() - self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(Document.on_organization.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) @override_settings(OCR_AUTO_OCR=False) class OfficeDocumentTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -164,7 +168,8 @@ class OfficeDocumentTestCase(TestCase): @override_settings(OCR_AUTO_OCR=False) class MultiPageTiffTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -189,7 +194,8 @@ class MultiPageTiffTestCase(TestCase): @override_settings(OCR_AUTO_OCR=False) class DocumentVersionTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -238,7 +244,8 @@ class DocumentVersionTestCase(TestCase): @override_settings(OCR_AUTO_OCR=False) class DocumentManagerTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) @@ -246,7 +253,7 @@ class DocumentManagerTestCase(TestCase): self.document_type.delete() def test_document_stubs_deletion(self): - document_stub = Document.objects.create( + document_stub = Document.on_organization.create( document_type=self.document_type ) @@ -267,7 +274,8 @@ class DocumentManagerTestCase(TestCase): @override_settings(OCR_AUTO_OCR=False) class NewVersionBlockTestCase(TestCase): def setUp(self): - self.document_type = DocumentType.objects.create( + create_default_organization() + self.document_type = DocumentType.on_organization.create( label=TEST_DOCUMENT_TYPE ) diff --git a/mayan/apps/documents/tests/test_organization_views.py b/mayan/apps/documents/tests/test_organization_views.py index 2baced6680..3aa5aed7c5 100644 --- a/mayan/apps/documents/tests/test_organization_views.py +++ b/mayan/apps/documents/tests/test_organization_views.py @@ -31,10 +31,10 @@ class DocumentOrganizationViewTestCase(OrganizationViewTestCase): if self.document_type.pk: self.document_type.delete() - def test_document_delete_view(self): + def test_document_to_trash_view(self): with self.settings(ORGANIZATION_ID=self.organization_b.pk): response = self.post( - 'documents:document_delete', args=(self.document.pk,) + 'documents:document_trash', args=(self.document.pk,) ) self.assertEqual(response.status_code, 404) diff --git a/mayan/apps/documents/tests/test_views.py b/mayan/apps/documents/tests/test_views.py index 9b80054c8d..592f21ce28 100644 --- a/mayan/apps/documents/tests/test_views.py +++ b/mayan/apps/documents/tests/test_views.py @@ -15,7 +15,7 @@ from user_management.tests.literals import ( from ..literals import DEFAULT_DELETE_PERIOD, DEFAULT_DELETE_TIME_UNIT from ..models import ( - DeletedDocument, Document, DocumentType, HASH_FUNCTION + Document, DocumentType, TrashedDocument, HASH_FUNCTION ) from ..permissions import ( permission_document_create, permission_document_delete, @@ -482,20 +482,20 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase): def test_trash_can_empty_view_no_permissions(self): self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD) self.document.delete() - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) response = self.post('documents:trash_can_empty') self.assertEqual(response.status_code, 403) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) def test_trash_can_empty_view_with_permission(self): self.login( username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD ) self.document.delete() - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) self.role.permissions.add( permission_empty_trash.stored_permission @@ -505,7 +505,7 @@ class DocumentsViewsTestCase(GenericDocumentViewTestCase): self.assertContains( response, text='emptied successfully', status_code=200 ) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) self.assertEqual(Document.objects.count(), 0) def test_document_version_revert_no_permission(self): @@ -724,7 +724,7 @@ class DocumentTypeViewsTestCase(GenericDocumentViewTestCase): self.assertEqual(self.document_type.filenames.count(), 1) -class DeletedDocumentTestCase(GenericDocumentViewTestCase): +class TrashedDocumentTestCase(GenericDocumentViewTestCase): def test_document_restore_view_no_permission(self): self.login( username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD @@ -736,7 +736,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): 'documents:document_restore', args=(self.document.pk,) ) self.assertEqual(response.status_code, 403) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) self.assertEqual(Document.objects.count(), 0) def test_document_restore_view_with_permission(self): @@ -753,7 +753,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): follow=True ) self.assertContains(response, text='restored', status_code=200) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) self.assertEqual(Document.objects.count(), 1) def test_document_trash_no_permissions(self): @@ -766,7 +766,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): ) self.assertEqual(response.status_code, 403) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) self.assertEqual(Document.objects.count(), 1) def test_document_trash_with_permissions(self): @@ -784,7 +784,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): ) self.assertContains(response, text='success', status_code=200) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) self.assertEqual(Document.objects.count(), 0) def test_document_delete_no_permissions(self): @@ -794,14 +794,14 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): self.document.delete() self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) response = self.post( 'documents:document_delete', args=(self.document.pk,), ) self.assertEqual(response.status_code, 403) self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) def test_document_delete_with_permissions(self): self.login( @@ -810,7 +810,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): self.document.delete() self.assertEqual(Document.objects.count(), 0) - self.assertEqual(DeletedDocument.objects.count(), 1) + self.assertEqual(TrashedDocument.objects.count(), 1) self.role.permissions.add( permission_document_delete.stored_permission @@ -822,7 +822,7 @@ class DeletedDocumentTestCase(GenericDocumentViewTestCase): ) self.assertContains(response, text='success', status_code=200) - self.assertEqual(DeletedDocument.objects.count(), 0) + self.assertEqual(TrashedDocument.objects.count(), 0) self.assertEqual(Document.objects.count(), 0) def test_deleted_document_list_view_no_permissions(self): diff --git a/mayan/apps/documents/urls.py b/mayan/apps/documents/urls.py index c7dfd59cfd..b31a9e3f99 100644 --- a/mayan/apps/documents/urls.py +++ b/mayan/apps/documents/urls.py @@ -3,8 +3,8 @@ from __future__ import unicode_literals from django.conf.urls import patterns, url from .api_views import ( - APIDeletedDocumentListView, APIDeletedDocumentRestoreView, - APIDeletedDocumentView, APIDocumentDownloadView, APIDocumentView, + APITrashedDocumentListView, APITrashedDocumentRestoreView, + APITrashedDocumentView, APIDocumentDownloadView, APIDocumentView, APIDocumentListView, APIDocumentVersionDownloadView, APIDocumentPageImageView, APIDocumentPageView, APIDocumentTypeDocumentListView, APIDocumentTypeListView, @@ -14,17 +14,16 @@ from .api_views import ( ) from .settings import setting_print_size, setting_display_size from .views import ( - ClearImageCacheView, DeletedDocumentDeleteView, - DeletedDocumentDeleteManyView, DeletedDocumentListView, DocumentEditView, - DocumentListView, DocumentPageView, DocumentPageListView, - DocumentPageViewResetView, DocumentPreviewView, DocumentRestoreView, - DocumentRestoreManyView, DocumentTrashView, DocumentTrashManyView, - DocumentTypeCreateView, DocumentTypeDeleteView, + ClearImageCacheView, DocumentEditView, DocumentListView, DocumentPageView, + DocumentPageListView, DocumentPageViewResetView, DocumentPreviewView, + DocumentRestoreView, DocumentRestoreManyView, DocumentTrashView, + DocumentTrashManyView, DocumentTypeCreateView, DocumentTypeDeleteView, DocumentTypeDocumentListView, DocumentTypeFilenameCreateView, DocumentTypeFilenameDeleteView, DocumentTypeFilenameEditView, DocumentTypeFilenameListView, DocumentTypeListView, DocumentTypeEditView, DocumentVersionListView, DocumentVersionRevertView, DocumentView, - EmptyTrashCanView, RecentDocumentListView + EmptyTrashCanView, RecentDocumentListView, TrashedDocumentDeleteView, + TrashedDocumentDeleteManyView, TrashedDocumentListView ) urlpatterns = patterns( @@ -35,7 +34,7 @@ urlpatterns = patterns( name='document_list_recent' ), url( - r'^list/deleted/$', DeletedDocumentListView.as_view(), + r'^list/deleted/$', TrashedDocumentListView.as_view(), name='document_list_deleted' ), @@ -56,11 +55,11 @@ urlpatterns = patterns( name='document_multiple_restore' ), url( - r'^(?P\d+)/delete/$', DeletedDocumentDeleteView.as_view(), + r'^(?P\d+)/delete/$', TrashedDocumentDeleteView.as_view(), name='document_delete' ), url( - r'^multiple/delete/$', DeletedDocumentDeleteManyView.as_view(), + r'^multiple/delete/$', TrashedDocumentDeleteManyView.as_view(), name='document_multiple_delete' ), url( @@ -242,18 +241,6 @@ urlpatterns = patterns( api_urls = patterns( '', - url( - r'^trashed_documents/$', APIDeletedDocumentListView.as_view(), - name='trasheddocument-list' - ), - url( - r'^trashed_documents/(?P[0-9]+)/$', - APIDeletedDocumentView.as_view(), name='trasheddocument-detail' - ), - url( - r'^trashed_documents/(?P[0-9]+)/restore/$', - APIDeletedDocumentRestoreView.as_view(), name='trasheddocument-restore' - ), url(r'^documents/$', APIDocumentListView.as_view(), name='document-list'), url( r'^documents/recent/$', APIRecentDocumentListView.as_view(), @@ -304,4 +291,16 @@ api_urls = patterns( r'^document_types/$', APIDocumentTypeListView.as_view(), name='documenttype-list' ), + url( + r'^trashed_documents/$', APITrashedDocumentListView.as_view(), + name='trasheddocument-list' + ), + url( + r'^trashed_documents/(?P[0-9]+)/$', + APITrashedDocumentView.as_view(), name='trasheddocument-detail' + ), + url( + r'^trashed_documents/(?P[0-9]+)/restore/$', + APITrashedDocumentRestoreView.as_view(), name='trasheddocument-restore' + ), ) diff --git a/mayan/apps/documents/views.py b/mayan/apps/documents/views.py index d3e8c7df0e..9c5ccd0567 100644 --- a/mayan/apps/documents/views.py +++ b/mayan/apps/documents/views.py @@ -38,8 +38,8 @@ from .forms import ( ) from .literals import DOCUMENT_IMAGE_TASK_TIMEOUT, PAGE_RANGE_RANGE from .models import ( - DeletedDocument, Document, DocumentType, DocumentPage, - DocumentTypeFilename, DocumentVersion, RecentDocument + Document, DocumentType, DocumentPage, DocumentTypeFilename, + DocumentVersion, RecentDocument, TrashedDocument ) from .permissions import ( permission_document_delete, permission_document_download, @@ -81,84 +81,19 @@ class DocumentListView(SingleObjectListView): 'hide_links': True, 'title': _('All documents'), } - object_permission = permission_document_view def get_document_queryset(self): - return Document.on_organization.defer('description', 'uuid', 'date_added', 'language', 'in_trash', 'deleted_date_time').all() + return Document.on_organization.defer( + 'description', 'uuid', 'date_added', 'language', 'in_trash', + 'deleted_date_time' + ).all() def get_queryset(self): self.queryset = self.get_document_queryset().filter(is_stub=False) return super(DocumentListView, self).get_queryset() -class DeletedDocumentListView(DocumentListView): - object_permission = None - - extra_context = { - 'hide_link': True, - 'title': _('Documents in trash'), - } - - def get_document_queryset(self): - queryset = Document.trash.filter(document_type__organization__id=settings.ORGANIZATION_ID) - - try: - Permission.check_permissions( - self.request.user, (permission_document_view,) - ) - except PermissionDenied: - queryset = AccessControlList.objects.filter_by_access( - permission_document_view, self.request.user, queryset - ) - - return DeletedDocument.objects.filter( - pk__in=queryset.values_list('pk', flat=True) - ) - - -class DeletedDocumentDeleteView(ConfirmView): - extra_context = { - 'title': _('Delete the selected document?') - } - - def object_action(self, instance): - source_document = get_object_or_404( - Document.passthrough.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=instance.pk - ) - - try: - Permission.check_permissions( - self.request.user, (permission_document_delete,) - ) - except PermissionDenied: - AccessControlList.objects.check_access( - permission_document_delete, self.request.user, source_document - ) - - instance.delete() - - def view_action(self): - instance = get_object_or_404(DeletedDocument, pk=self.kwargs['pk']) - self.object_action(instance=instance) - messages.success( - self.request, _('Document: %(document)s deleted.') % { - 'document': instance - } - ) - - -class DeletedDocumentDeleteManyView(MultipleInstanceActionMixin, DeletedDocumentDeleteView): - extra_context = { - 'title': _('Delete the selected documents?') - } - success_message = '%(count)d document deleted.' - success_message_plural = '%(count)d documents deleted.' - - def get_queryset(self): - return DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) - - class DocumentEditView(SingleObjectEditView): form_class = DocumentForm object_permission = permission_document_properties_edit @@ -176,14 +111,14 @@ class DocumentEditView(SingleObjectEditView): 'title': _('Edit properties of document: %s') % self.get_object(), } - def get_queryset(self): - return Document.on_organization.all() - def get_post_action_redirect(self): return reverse( 'documents:document_properties', args=(self.get_object().pk,) ) + def get_queryset(self): + return Document.on_organization.all() + def get_save_extra_data(self): return { '_user': self.request.user @@ -197,7 +132,7 @@ class DocumentRestoreView(ConfirmView): def object_action(self, instance): source_document = get_object_or_404( - Document.passthrough.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=instance.pk + Document, pk=instance.pk ) try: @@ -212,7 +147,7 @@ class DocumentRestoreView(ConfirmView): instance.restore() def view_action(self): - instance = get_object_or_404(DeletedDocument, pk=self.kwargs['pk']) + instance = get_object_or_404(TrashedDocument, pk=self.kwargs['pk']) self.object_action(instance=instance) @@ -227,12 +162,10 @@ class DocumentRestoreManyView(MultipleInstanceActionMixin, DocumentRestoreView): extra_context = { 'title': _('Restore the selected documents?') } + model = TrashedDocument success_message = '%(count)d document restored.' success_message_plural = '%(count)d documents restored.' - def get_queryset(self): - return DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) - class DocumentPageListView(SingleObjectListView): def dispatch(self, request, *args, **kwargs): @@ -308,7 +241,9 @@ class DocumentPageView(SimpleView): } def get_object(self): - return get_object_or_404(DocumentPage.objects.filter(document_version__document__document_type__organization__pk=settings.ORGANIZATION_ID), pk=self.kwargs['pk']) + return get_object_or_404( + DocumentPage.on_organization, pk=self.kwargs['pk'] + ) class DocumentPageViewResetView(RedirectView): @@ -534,7 +469,7 @@ class DocumentTypeFilenameEditView(SingleObjectEditView): ) def get_queryset(self): - return DocumentTypeFilename.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) + return DocumentTypeFilename.on_organization.all() class DocumentTypeFilenameDeleteView(SingleObjectDeleteView): @@ -561,15 +496,16 @@ class DocumentTypeFilenameDeleteView(SingleObjectDeleteView): ) def get_queryset(self): - return DocumentTypeFilename.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) + return DocumentTypeFilename.on_organization.all() class DocumentTypeFilenameListView(SingleObjectListView): - model = DocumentType view_permission = permission_document_type_view def get_document_type(self): - return get_object_or_404(DocumentType, pk=self.kwargs['pk']) + return get_object_or_404( + DocumentType.on_organization, pk=self.kwargs['pk'] + ) def get_extra_context(self): return { @@ -618,7 +554,6 @@ class DocumentVersionListView(SingleObjectListView): class DocumentVersionRevertView(ConfirmView): - # TODO: organization filter object_permission = permission_document_version_revert object_permission_related = 'document' @@ -632,7 +567,9 @@ class DocumentVersionRevertView(ConfirmView): } def get_object(self): - return get_object_or_404(DocumentVersion, pk=self.kwargs['pk']) + return get_object_or_404( + DocumentVersion.on_organization, pk=self.kwargs['pk'] + ) def view_action(self): try: @@ -668,17 +605,16 @@ class DocumentView(SingleObjectDetailView): class EmptyTrashCanView(ConfirmView): - # TODO: organization filter + action_cancel_redirect = post_action_redirect = reverse_lazy( + 'documents:document_list_deleted' + ) extra_context = { 'title': _('Empty trash?') } view_permission = permission_empty_trash - action_cancel_redirect = post_action_redirect = reverse_lazy( - 'documents:document_list_deleted' - ) def view_action(self): - for deleted_document in DeletedDocument.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID): + for deleted_document in TrashedDocument.objects.all(): deleted_document.delete() messages.success(self.request, _('Trash emptied successfully')) @@ -694,6 +630,70 @@ class RecentDocumentListView(DocumentListView): return RecentDocument.objects.get_for_user(self.request.user) +class TrashedDocumentListView(DocumentListView): + extra_context = { + 'hide_link': True, + 'title': _('Documents in trash'), + } + object_permission = None + + def get_document_queryset(self): + queryset = Document.trash.all() + + try: + Permission.check_permissions( + self.request.user, (permission_document_view,) + ) + except PermissionDenied: + queryset = AccessControlList.objects.filter_by_access( + permission_document_view, self.request.user, queryset + ) + + return TrashedDocument.objects.filter( + pk__in=queryset.values_list('pk', flat=True) + ) + + +class TrashedDocumentDeleteView(ConfirmView): + extra_context = { + 'title': _('Delete the selected document?') + } + + def object_action(self, instance): + source_document = get_object_or_404( + Document.on_organization, pk=instance.pk + ) + + try: + Permission.check_permissions( + self.request.user, (permission_document_delete,) + ) + except PermissionDenied: + AccessControlList.objects.check_access( + permission_document_delete, self.request.user, source_document + ) + + instance.delete() + + def view_action(self): + instance = get_object_or_404(TrashedDocument, pk=self.kwargs['pk']) + self.object_action(instance=instance) + messages.success( + self.request, _('Document: %(document)s deleted.') % { + 'document': instance + } + ) + + +class TrashedDocumentDeleteManyView(MultipleInstanceActionMixin, TrashedDocumentDeleteView): + extra_context = { + 'title': _('Delete the selected documents?') + } + model = TrashedDocument + success_message = '%(count)d document deleted.' + success_message_plural = '%(count)d documents deleted.' + + def document_document_type_edit(request, document_id=None, document_id_list=None): post_action_redirect = None @@ -778,7 +778,12 @@ def document_multiple_document_type_edit(request): # TODO: Get rid of this view and convert widget to use API and base64 only images def get_document_image(request, document_id, size=setting_preview_size.value): - document = get_object_or_404(Document.passthrough.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=document_id) + # Special case. Allow all active and trashed documents but filter by + # organization, to be able to produce thumbnails for all documents. + document = get_object_or_404( + Document.filter(document_type__in=DocumentType.on_organization.all()), + pk=document_id + ) try: Permission.check_permissions(request.user, (permission_document_view,)) except PermissionDenied: @@ -810,7 +815,7 @@ def get_document_image(request, document_id, size=setting_preview_size.value): def document_download(request, document_id=None, document_id_list=None, document_version_pk=None): previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) - queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) + queryset = Document.on_organization.all() if document_id: documents = queryset.filter(pk=document_id) @@ -961,7 +966,7 @@ def document_multiple_download(request): def document_update_page_count(request, document_id=None, document_id_list=None): - queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) + queryset = Document.on_organization.all() if document_id: documents = queryset.filter(pk=document_id) @@ -1026,7 +1031,7 @@ def document_multiple_update_page_count(request): def document_clear_transformations(request, document_id=None, document_id_list=None): - queryset = Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID) + queryset = Document.on_organization.all() if document_id: documents = queryset.filter(pk=document_id) @@ -1108,7 +1113,7 @@ def document_multiple_clear_transformations(request): def document_page_navigation_next(request, document_page_id): - document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id) + document_page = get_object_or_404(DocumentPage.on_organization, pk=document_page_id) try: Permission.check_permissions(request.user, (permission_document_view,)) @@ -1126,7 +1131,7 @@ def document_page_navigation_next(request, document_page_id): def document_page_navigation_previous(request, document_page_id): - document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id) + document_page = get_object_or_404(DocumentPage.on_organization, pk=document_page_id) try: Permission.check_permissions(request.user, (permission_document_view,)) @@ -1144,7 +1149,7 @@ def document_page_navigation_previous(request, document_page_id): def document_page_navigation_first(request, document_page_id): - document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id) + document_page = get_object_or_404(DocumentPage.on_organization, pk=document_page_id) document_page = get_object_or_404(document_page.siblings, page_number=1) try: @@ -1158,7 +1163,7 @@ def document_page_navigation_first(request, document_page_id): def document_page_navigation_last(request, document_page_id): - document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id) + document_page = get_object_or_404(DocumentPage.on_organization, pk=document_page_id) document_page = get_object_or_404(document_page.siblings, page_number=document_page.siblings.count()) try: @@ -1172,7 +1177,7 @@ def document_page_navigation_last(request, document_page_id): def transform_page(request, document_page_id, zoom_function=None, rotation_function=None): - document_page = get_object_or_404(DocumentPage.objects.filter(document__document_type__organization__id=settings.ORGANIZATION_ID), pk=document_page_id) + document_page = get_object_or_404(DocumentPage.on_organization, pk=document_page_id) try: Permission.check_permissions(request.user, (permission_document_view,)) @@ -1235,7 +1240,7 @@ def document_page_rotate_left(request, document_page_id): def document_print(request, document_id): - document = get_object_or_404(Document.objects.filter(document_type__organization__id=settings.ORGANIZATION_ID), pk=document_id) + document = get_object_or_404(Document.on_organization, pk=document_id) try: Permission.check_permissions(request.user, (permission_document_print,))