Rename view and models from "deleted document" to "trashed document". Implement document level organization support via custom 'on_organization' manager. Unfilter default 'objects' manager to operate on all documents in the database.
This commit is contained in:
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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<pk>\d+)/delete/$', DeletedDocumentDeleteView.as_view(),
|
||||
r'^(?P<pk>\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<pk>[0-9]+)/$',
|
||||
APIDeletedDocumentView.as_view(), name='trasheddocument-detail'
|
||||
),
|
||||
url(
|
||||
r'^trashed_documents/(?P<pk>[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<pk>[0-9]+)/$',
|
||||
APITrashedDocumentView.as_view(), name='trasheddocument-detail'
|
||||
),
|
||||
url(
|
||||
r'^trashed_documents/(?P<pk>[0-9]+)/restore/$',
|
||||
APITrashedDocumentRestoreView.as_view(), name='trasheddocument-restore'
|
||||
),
|
||||
)
|
||||
|
||||
@@ -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,))
|
||||
|
||||
Reference in New Issue
Block a user