Move add_to_class functions to their own module

* The new module is called methods.py and found on each app.
* Add keyword arguments to add_to_class instances.
* Remove catch all exception handling for the check in and
  check out views.
* Improve checkouts tests code reducing redundant code.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2019-04-11 18:00:41 -04:00
parent a12c90268f
commit 456c322c19
33 changed files with 375 additions and 338 deletions

View File

@@ -10,6 +10,11 @@
* Split document app models into separate modules. * Split document app models into separate modules.
* Split workflow views into separate modules. * Split workflow views into separate modules.
* Add custom DatabaseWarning to tag the SQLite usage warning. * Add custom DatabaseWarning to tag the SQLite usage warning.
* Add keyword arguments to add_to_class instances.
* Move add_to_class function to their own module called methods.py
* Remove catch all exception handling for the check in and
check out views.
* Improve checkouts tests code reducing redundant code.
3.1.11 (2019-04-XX) 3.1.11 (2019-04-XX)
=================== ===================

View File

@@ -24,7 +24,9 @@ class ModelPermission(object):
app_label='acls', model_name='AccessControlList' app_label='acls', model_name='AccessControlList'
) )
model.add_to_class('acls', GenericRelation(AccessControlList)) model.add_to_class(
name='acls', value=GenericRelation(AccessControlList)
)
@classmethod @classmethod
def get_classes(cls, as_content_type=False): def get_classes(cls, as_content_type=False):

View File

@@ -39,7 +39,7 @@ class APIDocumentCabinetListView(generics.ListAPIView):
obj=document obj=document
) )
queryset = document.document_cabinets().all() queryset = document.get_cabinets()
return queryset return queryset

View File

@@ -21,6 +21,7 @@ from .links import (
link_multiple_document_cabinet_remove link_multiple_document_cabinet_remove
) )
from .menus import menu_cabinets from .menus import menu_cabinets
from .methods import method_get_document_cabinets
from .permissions import ( from .permissions import (
permission_cabinet_add_document, permission_cabinet_delete, permission_cabinet_add_document, permission_cabinet_delete,
permission_cabinet_edit, permission_cabinet_remove_document, permission_cabinet_edit, permission_cabinet_remove_document,
@@ -52,8 +53,7 @@ class CabinetsApp(MayanAppConfig):
# Add explicit order_by as DocumentCabinet ordering Meta option has no # Add explicit order_by as DocumentCabinet ordering Meta option has no
# effect. # effect.
Document.add_to_class( Document.add_to_class(
'document_cabinets', name='document_cabinets', value=method_get_document_cabinets
lambda document: DocumentCabinet.objects.filter(documents=document).order_by('parent__label', 'label')
) )
ModelPermission.register( ModelPermission.register(

View File

@@ -0,0 +1,20 @@
from __future__ import unicode_literals
from django.apps import apps
from django.utils.translation import ugettext_lazy as _
def method_get_document_cabinets(self):
DocumentCabinet = apps.get_model(
app_label='cabinets', model_name='DocumentCabinet'
)
return DocumentCabinet.objects.filter(documents=self).order_by(
'parent__label', 'label'
)
method_get_document_cabinets.help_text = _(
'Return a list of cabinets containing the document'
)
method_get_document_cabinets.short_description = _('get_cabinets()')

View File

@@ -219,7 +219,7 @@ class DocumentCabinetListView(CabinetListView):
} }
def get_object_list(self): def get_object_list(self):
return self.document.document_cabinets().all() return self.document.document_cabinets()
class DocumentAddToCabinetView(MultipleObjectFormActionView): class DocumentAddToCabinetView(MultipleObjectFormActionView):

View File

@@ -43,7 +43,7 @@ def widget_document_cabinets(document, user):
) )
cabinets = AccessControlList.objects.filter_by_access( cabinets = AccessControlList.objects.filter_by_access(
permission_cabinet_view, user, queryset=document.document_cabinets().all() permission_cabinet_view, user, queryset=document.document_cabinets()
) )
return format_html_join( return format_html_join(

View File

@@ -7,8 +7,8 @@ from mayan.apps.documents.permissions import permission_document_view
from .models import DocumentCheckout from .models import DocumentCheckout
from .permissions import ( from .permissions import (
permission_document_checkin, permission_document_checkin_override, permission_document_check_in, permission_document_check_in_override,
permission_document_checkout_detail_view permission_document_check_out_detail_view
) )
from .serializers import ( from .serializers import (
DocumentCheckoutSerializer, NewDocumentCheckoutSerializer DocumentCheckoutSerializer, NewDocumentCheckoutSerializer
@@ -38,7 +38,7 @@ class APICheckedoutDocumentListView(generics.ListCreateAPIView):
queryset=DocumentCheckout.objects.checked_out_documents() queryset=DocumentCheckout.objects.checked_out_documents()
) )
filtered_documents = AccessControlList.objects.filter_by_access( filtered_documents = AccessControlList.objects.filter_by_access(
permission=permission_document_checkout_detail_view, user=self.request.user, permission=permission_document_check_out_detail_view, user=self.request.user,
queryset=filtered_documents queryset=filtered_documents
) )
@@ -61,7 +61,7 @@ class APICheckedoutDocumentView(generics.RetrieveDestroyAPIView):
queryset=DocumentCheckout.objects.checked_out_documents() queryset=DocumentCheckout.objects.checked_out_documents()
) )
filtered_documents = AccessControlList.objects.filter_by_access( filtered_documents = AccessControlList.objects.filter_by_access(
permission=permission_document_checkout_detail_view, user=self.request.user, permission=permission_document_check_out_detail_view, user=self.request.user,
queryset=filtered_documents queryset=filtered_documents
) )
@@ -78,12 +78,12 @@ class APICheckedoutDocumentView(generics.RetrieveDestroyAPIView):
if document.checkout_info().user == request.user: if document.checkout_info().user == request.user:
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkin, user=request.user, permissions=permission_document_check_in, user=request.user,
obj=document obj=document
) )
else: else:
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkin_override, permissions=permission_document_check_in_override,
user=request.user, obj=document user=request.user, obj=document
) )

View File

@@ -21,13 +21,17 @@ from .events import (
) )
from .handlers import check_new_version_creation from .handlers import check_new_version_creation
from .links import ( from .links import (
link_checkin_document, link_checkout_document, link_checkout_info, link_check_in_document, link_check_out_document, link_check_out_info,
link_checkout_list link_check_out_list
) )
from .literals import CHECK_EXPIRED_CHECK_OUTS_INTERVAL from .literals import CHECK_EXPIRED_CHECK_OUTS_INTERVAL
from .methods import (
method_check_in, method_get_check_out_info, method_get_check_out_state,
method_is_checked_out
)
from .permissions import ( from .permissions import (
permission_document_checkin, permission_document_checkin_override, permission_document_check_in, permission_document_check_in_override,
permission_document_checkout, permission_document_checkout_detail_view permission_document_check_out, permission_document_check_out_detail_view
) )
from .queues import * # NOQA from .queues import * # NOQA
from .tasks import task_check_expired_check_outs # NOQA from .tasks import task_check_expired_check_outs # NOQA
@@ -52,29 +56,15 @@ class CheckoutsApp(MayanAppConfig):
app_label='documents', model_name='DocumentVersion' app_label='documents', model_name='DocumentVersion'
) )
DocumentCheckout = self.get_model('DocumentCheckout') Document.add_to_class(name='check_in', value=method_check_in)
Document.add_to_class( Document.add_to_class(
'check_in', name='get_check_out_info', value=method_get_check_out_info
lambda document, user=None: DocumentCheckout.objects.check_in_document(document, user)
) )
Document.add_to_class( Document.add_to_class(
'checkout_info', name='get_check_out_state', value=method_get_check_out_state
lambda document: DocumentCheckout.objects.document_checkout_info(
document
)
) )
Document.add_to_class( Document.add_to_class(
'checkout_state', name='is_checked_out', value=method_is_checked_out
lambda document: DocumentCheckout.objects.document_checkout_state(
document
)
)
Document.add_to_class(
'is_checked_out',
lambda document: DocumentCheckout.objects.is_document_checked_out(
document
)
) )
ModelEventType.register( ModelEventType.register(
@@ -86,10 +76,10 @@ class CheckoutsApp(MayanAppConfig):
ModelPermission.register( ModelPermission.register(
model=Document, permissions=( model=Document, permissions=(
permission_document_checkout, permission_document_check_out,
permission_document_checkin, permission_document_check_in,
permission_document_checkin_override, permission_document_check_in_override,
permission_document_checkout_detail_view permission_document_check_out_detail_view
) )
) )
@@ -123,13 +113,13 @@ class CheckoutsApp(MayanAppConfig):
widget=DashboardWidgetTotalCheckouts, order=-1 widget=DashboardWidgetTotalCheckouts, order=-1
) )
menu_facet.bind_links(links=(link_checkout_info,), sources=(Document,)) menu_facet.bind_links(links=(link_check_out_info,), sources=(Document,))
menu_main.bind_links(links=(link_checkout_list,), position=98) menu_main.bind_links(links=(link_check_out_list,), position=98)
menu_sidebar.bind_links( menu_sidebar.bind_links(
links=(link_checkout_document, link_checkin_document), links=(link_check_out_document, link_check_in_document),
sources=( sources=(
'checkouts:checkout_info', 'checkouts:checkout_document', 'checkouts:check_out_info', 'checkouts:check_out_document',
'checkouts:checkin_document' 'checkouts:check_in_document'
) )
) )

View File

@@ -7,14 +7,14 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.common.classes import DashboardWidgetNumeric from mayan.apps.common.classes import DashboardWidgetNumeric
from mayan.apps.documents.permissions import permission_document_view from mayan.apps.documents.permissions import permission_document_view
from .icons import icon_dashboard_checkouts from .icons import icon_dashboard_check_outs
from .permissions import permission_document_checkout_detail_view from .permissions import permission_document_check_out_detail_view
class DashboardWidgetTotalCheckouts(DashboardWidgetNumeric): class DashboardWidgetTotalCheckouts(DashboardWidgetNumeric):
icon_class = icon_dashboard_checkouts icon_class = icon_dashboard_check_outs
label = _('Checkedout documents') label = _('Checked out documents')
link = reverse_lazy('checkouts:checkout_list') link = reverse_lazy('checkouts:check_out_list')
def render(self, request): def render(self, request):
AccessControlList = apps.get_model( AccessControlList = apps.get_model(
@@ -24,13 +24,13 @@ class DashboardWidgetTotalCheckouts(DashboardWidgetNumeric):
app_label='checkouts', model_name='DocumentCheckout' app_label='checkouts', model_name='DocumentCheckout'
) )
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.filter_by_access(
permission=permission_document_checkout_detail_view, permission=permission_document_check_out_detail_view,
user=request.user, queryset=DocumentCheckout.objects.checked_out_documents(),
queryset=DocumentCheckout.objects.checked_out_documents() user=request.user
) )
queryset = AccessControlList.objects.filter_by_access( queryset = AccessControlList.objects.filter_by_access(
permission=permission_document_view, user=request.user, permission=permission_document_view, queryset=queryset,
queryset=queryset user=request.user
) )
self.count = queryset.count() self.count = queryset.count()
return super(DashboardWidgetTotalCheckouts, self).render(request) return super(DashboardWidgetTotalCheckouts, self).render(request)

View File

@@ -26,12 +26,14 @@ class DocumentCheckoutDefailForm(DetailForm):
extra_fields = ( extra_fields = (
{ {
'label': _('Document status'), 'label': _('Document status'),
'field': lambda instance: STATE_LABELS[instance.checkout_state()] 'field': lambda instance: STATE_LABELS[
instance.get_check_out_state()
]
}, },
) )
if instance.is_checked_out(): if instance.is_checked_out():
checkout_info = instance.checkout_info() checkout_info = instance.get_check_out_info()
extra_fields += ( extra_fields += (
{ {
'label': _('User'), 'label': _('User'),

View File

@@ -2,7 +2,7 @@ from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon from mayan.apps.appearance.classes import Icon
icon_checkout_info = Icon(driver_name='fontawesome', symbol='shopping-cart') icon_check_out_info = Icon(driver_name='fontawesome', symbol='shopping-cart')
icon_dashboard_checkouts = Icon( icon_dashboard_check_outs = Icon(
driver_name='fontawesome', symbol='shopping-cart' driver_name='fontawesome', symbol='shopping-cart'
) )

View File

@@ -4,11 +4,11 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation import Link from mayan.apps.navigation import Link
from .icons import icon_checkout_info from .icons import icon_check_out_info
from .permissions import ( from .permissions import (
permission_document_checkout, permission_document_checkin, permission_document_check_out, permission_document_check_in,
permission_document_checkin_override, permission_document_check_in_override,
permission_document_checkout_detail_view permission_document_check_out_detail_view
) )
@@ -28,22 +28,22 @@ def is_not_checked_out(context):
return True return True
link_checkout_list = Link( link_check_out_list = Link(
icon_class=icon_checkout_info, text=_('Checkouts'), icon_class=icon_check_out_info, text=_('Checkouts'),
view='checkouts:checkout_list' view='checkouts:check_out_list'
) )
link_checkout_document = Link( link_check_out_document = Link(
args='object.pk', condition=is_not_checked_out, args='object.pk', condition=is_not_checked_out,
permissions=(permission_document_checkout,), permissions=(permission_document_check_out,),
text=_('Check out document'), view='checkouts:checkout_document', text=_('Check out document'), view='checkouts:check_out_document',
) )
link_checkin_document = Link( link_check_in_document = Link(
args='object.pk', condition=is_checked_out, permissions=( args='object.pk', condition=is_checked_out, permissions=(
permission_document_checkin, permission_document_checkin_override permission_document_check_in, permission_document_check_in_override
), text=_('Check in document'), view='checkouts:checkin_document', ), text=_('Check in document'), view='checkouts:check_in_document',
) )
link_checkout_info = Link( link_check_out_info = Link(
args='resolved_object.pk', icon_class=icon_checkout_info, permissions=( args='resolved_object.pk', icon_class=icon_check_out_info, permissions=(
permission_document_checkout_detail_view, permission_document_check_out_detail_view,
), text=_('Check in/out'), view='checkouts:checkout_info', ), text=_('Check in/out'), view='checkouts:check_out_info',
) )

View File

@@ -21,20 +21,20 @@ logger = logging.getLogger(__name__)
class DocumentCheckoutManager(models.Manager): class DocumentCheckoutManager(models.Manager):
def are_document_new_versions_allowed(self, document, user=None): def are_document_new_versions_allowed(self, document, user=None):
try: try:
checkout_info = self.document_checkout_info(document) check_out_info = self.document_check_out_info(document=document)
except DocumentNotCheckedOut: except DocumentNotCheckedOut:
return True return True
else: else:
return not checkout_info.block_new_version return not check_out_info.block_new_version
def check_in_document(self, document, user=None): def check_in_document(self, document, user=None):
try: try:
document_checkout = self.model.objects.get(document=document) document_check_out = self.model.objects.get(document=document)
except self.model.DoesNotExist: except self.model.DoesNotExist:
raise DocumentNotCheckedOut raise DocumentNotCheckedOut
else: else:
if user: if user:
if self.document_checkout_info(document=document).user != user: if self.get_check_out_info(document=document).user != user:
event_document_forceful_check_in.commit( event_document_forceful_check_in.commit(
actor=user, target=document actor=user, target=document
) )
@@ -43,13 +43,13 @@ class DocumentCheckoutManager(models.Manager):
else: else:
event_document_auto_check_in.commit(target=document) event_document_auto_check_in.commit(target=document)
document_checkout.delete() document_check_out.delete()
def check_in_expired_check_outs(self): def check_in_expired_check_outs(self):
for document in self.expired_check_outs(): for document in self.expired_check_outs():
document.check_in() document.check_in()
def checkout_document(self, document, expiration_datetime, user, block_new_version=True): def check_out_document(self, document, expiration_datetime, user, block_new_version=True):
return self.create( return self.create(
block_new_version=block_new_version, document=document, block_new_version=block_new_version, document=document,
expiration_datetime=expiration_datetime, user=user expiration_datetime=expiration_datetime, user=user
@@ -60,14 +60,14 @@ class DocumentCheckoutManager(models.Manager):
pk__in=self.model.objects.values('document__id') pk__in=self.model.objects.values('document__id')
) )
def document_checkout_info(self, document): def get_check_out_info(self, document):
try: try:
return self.model.objects.get(document=document) return self.model.objects.get(document=document)
except self.model.DoesNotExist: except self.model.DoesNotExist:
raise DocumentNotCheckedOut raise DocumentNotCheckedOut
def document_checkout_state(self, document): def get_check_out_state(self, document):
if self.is_document_checked_out(document=document): if self.is_checked_out(document=document):
return STATE_CHECKED_OUT return STATE_CHECKED_OUT
else: else:
return STATE_CHECKED_IN return STATE_CHECKED_IN
@@ -92,7 +92,7 @@ class DocumentCheckoutManager(models.Manager):
return self.get(document__pk=document.pk) return self.get(document__pk=document.pk)
def is_document_checked_out(self, document): def is_checked_out(self, document):
return self.filter(document=document).exists() return self.filter(document=document).exists()

View File

@@ -0,0 +1,34 @@
from __future__ import unicode_literals
from django.apps import apps
def method_check_in(self, user=None):
DocumentCheckout = apps.get_model(
app_label='checkouts', model_name='DocumentCheckout'
)
return DocumentCheckout.objects.check_in_document(
document=self, user=user
)
def method_get_check_out_info(self):
DocumentCheckout = apps.get_model(
app_label='checkouts', model_name='DocumentCheckout'
)
return DocumentCheckout.objects.get_check_out_info(document=self)
def method_get_check_out_state(self):
DocumentCheckout = apps.get_model(
app_label='checkouts', model_name='DocumentCheckout'
)
return DocumentCheckout.objects.get_check_out_state(document=self)
def method_is_checked_out(self):
DocumentCheckout = apps.get_model(
app_label='checkouts', model_name='DocumentCheckout'
)
return DocumentCheckout.objects.is_checked_out(document=self)

View File

@@ -6,15 +6,15 @@ from mayan.apps.permissions import PermissionNamespace
namespace = PermissionNamespace('checkouts', _('Document checkout')) namespace = PermissionNamespace('checkouts', _('Document checkout'))
permission_document_checkin = namespace.add_permission( permission_document_check_in = namespace.add_permission(
name='checkin_document', label=_('Check in documents') name='checkin_document', label=_('Check in documents')
) )
permission_document_checkin_override = namespace.add_permission( permission_document_check_in_override = namespace.add_permission(
name='checkin_document_override', label=_('Forcefully check in documents') name='checkin_document_override', label=_('Forcefully check in documents')
) )
permission_document_checkout = namespace.add_permission( permission_document_check_out = namespace.add_permission(
name='checkout_document', label=_('Check out documents') name='checkout_document', label=_('Check out documents')
) )
permission_document_checkout_detail_view = namespace.add_permission( permission_document_check_out_detail_view = namespace.add_permission(
name='checkout_detail_view', label=_('Check out details view') name='checkout_detail_view', label=_('Check out details view')
) )

View File

@@ -9,7 +9,7 @@ from mayan.apps.documents.models import Document
from mayan.apps.documents.serializers import DocumentSerializer from mayan.apps.documents.serializers import DocumentSerializer
from .models import DocumentCheckout from .models import DocumentCheckout
from .permissions import permission_document_checkout from .permissions import permission_document_check_out
class DocumentCheckoutSerializer(serializers.ModelSerializer): class DocumentCheckoutSerializer(serializers.ModelSerializer):
@@ -42,7 +42,7 @@ class NewDocumentCheckoutSerializer(serializers.ModelSerializer):
document = Document.objects.get(pk=validated_data.pop('document_pk')) document = Document.objects.get(pk=validated_data.pop('document_pk'))
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkout, permissions=permission_document_check_out,
user=self.context['request'].user, obj=document user=self.context['request'].user, obj=document
) )

View File

@@ -8,11 +8,13 @@ from ..models import DocumentCheckout
class DocumentCheckoutTestMixin(object): class DocumentCheckoutTestMixin(object):
def _checkout_document(self): def _check_out_document(self, user=None):
if not user:
user = self.user
expiration_datetime = now() + datetime.timedelta(days=1) expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document( self.test_check_out = DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.user, block_new_version=True user=user, block_new_version=True
) )
self.assertTrue(self.document.is_checked_out())

View File

@@ -1,10 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
from django.test import override_settings from django.test import override_settings
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.timezone import now
from rest_framework import status from rest_framework import status
@@ -14,12 +11,14 @@ from mayan.apps.rest_api.tests import BaseAPITestCase
from ..models import DocumentCheckout from ..models import DocumentCheckout
from ..permissions import ( from ..permissions import (
permission_document_checkout, permission_document_checkout_detail_view permission_document_check_out, permission_document_check_out_detail_view
) )
from .mixins import DocumentCheckoutTestMixin
@override_settings(OCR_AUTO_OCR=False) @override_settings(OCR_AUTO_OCR=False)
class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase): class CheckoutsAPITestCase(DocumentCheckoutTestMixin, DocumentTestMixin, BaseAPITestCase):
def setUp(self): def setUp(self):
super(CheckoutsAPITestCase, self).setUp() super(CheckoutsAPITestCase, self).setUp()
self.login_user() self.login_user()
@@ -27,32 +26,24 @@ class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase):
def _request_checkedout_document_view(self): def _request_checkedout_document_view(self):
return self.get( return self.get(
viewname='rest_api:checkedout-document-view', viewname='rest_api:checkedout-document-view',
args=(self.checkout.pk,) args=(self.test_check_out.pk,)
)
def _checkout_document(self):
expiration_datetime = now() + datetime.timedelta(days=1)
self.checkout = DocumentCheckout.objects.checkout_document(
document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True
) )
def test_checkedout_document_view_no_access(self): def test_checkedout_document_view_no_access(self):
self._checkout_document() self._check_out_document()
response = self._request_checkedout_document_view() response = self._request_checkedout_document_view()
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_checkedout_document_view_with_checkout_access(self): def test_checkedout_document_view_with_checkout_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_checkout_detail_view, obj=self.document permission=permission_document_check_out_detail_view, obj=self.document
) )
response = self._request_checkedout_document_view() response = self._request_checkedout_document_view()
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_checkedout_document_view_with_document_access(self): def test_checkedout_document_view_with_document_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_view, obj=self.document permission=permission_document_view, obj=self.document
) )
@@ -60,12 +51,12 @@ class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase):
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
def test_checkedout_document_view_with_access(self): def test_checkedout_document_view_with_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_view, obj=self.document permission=permission_document_view, obj=self.document
) )
self.grant_access( self.grant_access(
permission=permission_document_checkout_detail_view, obj=self.document permission=permission_document_check_out_detail_view, obj=self.document
) )
response = self._request_checkedout_document_view() response = self._request_checkedout_document_view()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -85,7 +76,7 @@ class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase):
self.assertEqual(DocumentCheckout.objects.count(), 0) self.assertEqual(DocumentCheckout.objects.count(), 0)
def test_document_checkout_with_access(self): def test_document_checkout_with_access(self):
self.grant_access(permission=permission_document_checkout, obj=self.document) self.grant_access(permission=permission_document_check_out, obj=self.document)
response = self._request_document_checkout_view() response = self._request_document_checkout_view()
self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual( self.assertEqual(
@@ -96,13 +87,13 @@ class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase):
return self.get(viewname='rest_api:checkout-document-list') return self.get(viewname='rest_api:checkout-document-list')
def test_checkout_list_view_no_access(self): def test_checkout_list_view_no_access(self):
self._checkout_document() self._check_out_document()
response = self._request_checkout_list_view() response = self._request_checkout_list_view()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNotContains(response=response, text=self.document.uuid) self.assertNotContains(response=response, text=self.document.uuid)
def test_checkout_list_view_with_document_access(self): def test_checkout_list_view_with_document_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_view, obj=self.document permission=permission_document_view, obj=self.document
) )
@@ -111,21 +102,21 @@ class CheckoutsAPITestCase(DocumentTestMixin, BaseAPITestCase):
self.assertNotContains(response=response, text=self.document.uuid) self.assertNotContains(response=response, text=self.document.uuid)
def test_checkout_list_view_with_checkout_access(self): def test_checkout_list_view_with_checkout_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_checkout_detail_view, obj=self.document permission=permission_document_check_out_detail_view, obj=self.document
) )
response = self._request_checkout_list_view() response = self._request_checkout_list_view()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNotContains(response=response, text=self.document.uuid) self.assertNotContains(response=response, text=self.document.uuid)
def test_checkout_list_view_with_access(self): def test_checkout_list_view_with_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
permission=permission_document_view, obj=self.document permission=permission_document_view, obj=self.document
) )
self.grant_access( self.grant_access(
permission=permission_document_checkout_detail_view, obj=self.document permission=permission_document_check_out_detail_view, obj=self.document
) )
response = self._request_checkout_list_view() response = self._request_checkout_list_view()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)

View File

@@ -2,9 +2,9 @@ from __future__ import unicode_literals
from mayan.apps.documents.tests import GenericDocumentViewTestCase from mayan.apps.documents.tests import GenericDocumentViewTestCase
from ..links import link_checkout_document, link_checkout_info from ..links import link_check_out_document, link_check_out_info
from ..permissions import ( from ..permissions import (
permission_document_checkout, permission_document_checkout_detail_view permission_document_check_out, permission_document_check_out_detail_view
) )
from .mixins import DocumentCheckoutTestMixin from .mixins import DocumentCheckoutTestMixin
@@ -19,7 +19,7 @@ class CheckoutLinksTestCase(DocumentCheckoutTestMixin, GenericDocumentViewTestCa
self.add_test_view(test_object=self.document) self.add_test_view(test_object=self.document)
context = self.get_test_view() context = self.get_test_view()
context['user'] = self.user context['user'] = self.user
return link_checkout_document.resolve(context=context) return link_check_out_document.resolve(context=context)
def test_checkout_link_no_access(self): def test_checkout_link_no_access(self):
resolved_link = self._resolve_checkout_link() resolved_link = self._resolve_checkout_link()
@@ -27,7 +27,7 @@ class CheckoutLinksTestCase(DocumentCheckoutTestMixin, GenericDocumentViewTestCa
def test_checkout_link_with_access(self): def test_checkout_link_with_access(self):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_checkout obj=self.document, permission=permission_document_check_out
) )
resolved_link = self._resolve_checkout_link() resolved_link = self._resolve_checkout_link()
self.assertNotEqual(resolved_link, None) self.assertNotEqual(resolved_link, None)
@@ -36,7 +36,7 @@ class CheckoutLinksTestCase(DocumentCheckoutTestMixin, GenericDocumentViewTestCa
self.add_test_view(test_object=self.document) self.add_test_view(test_object=self.document)
context = self.get_test_view() context = self.get_test_view()
context['user'] = self.user context['user'] = self.user
return link_checkout_info.resolve(context=context) return link_check_out_info.resolve(context=context)
def test_checkout_info_link_no_access(self): def test_checkout_info_link_no_access(self):
resolved_link = self._resolve_checkout_info_link() resolved_link = self._resolve_checkout_info_link()
@@ -44,7 +44,7 @@ class CheckoutLinksTestCase(DocumentCheckoutTestMixin, GenericDocumentViewTestCa
def test_checkout_info_link_with_access(self): def test_checkout_info_link_with_access(self):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_checkout_detail_view obj=self.document, permission=permission_document_check_out_detail_view
) )
resolved_link = self._resolve_checkout_info_link() resolved_link = self._resolve_checkout_info_link()
self.assertNotEqual(resolved_link, None) self.assertNotEqual(resolved_link, None)

View File

@@ -20,17 +20,17 @@ from ..models import DocumentCheckout, NewVersionBlock
@override_settings(OCR_AUTO_OCR=False) @override_settings(OCR_AUTO_OCR=False)
class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase): class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase):
def test_document_checkout(self): def test_document_check_out(self):
expiration_datetime = now() + datetime.timedelta(days=1) expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True user=self.admin_user, block_new_version=True
) )
self.assertTrue(self.document.is_checked_out()) self.assertTrue(self.document.is_checked_out())
self.assertTrue( self.assertTrue(
DocumentCheckout.objects.is_document_checked_out( DocumentCheckout.objects.is_checked_out(
document=self.document document=self.document
) )
) )
@@ -38,7 +38,7 @@ class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase):
def test_checkin_in(self): def test_checkin_in(self):
expiration_datetime = now() + datetime.timedelta(days=1) expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True user=self.admin_user, block_new_version=True
) )
@@ -47,21 +47,21 @@ class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase):
self.assertFalse(self.document.is_checked_out()) self.assertFalse(self.document.is_checked_out())
self.assertFalse( self.assertFalse(
DocumentCheckout.objects.is_document_checked_out( DocumentCheckout.objects.is_checked_out(
document=self.document document=self.document
) )
) )
def test_double_checkout(self): def test_double_check_out(self):
expiration_datetime = now() + datetime.timedelta(days=1) expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True user=self.admin_user, block_new_version=True
) )
with self.assertRaises(DocumentAlreadyCheckedOut): with self.assertRaises(DocumentAlreadyCheckedOut):
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, document=self.document,
expiration_datetime=expiration_datetime, user=self.admin_user, expiration_datetime=expiration_datetime, user=self.admin_user,
block_new_version=True block_new_version=True
@@ -71,10 +71,10 @@ class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase):
with self.assertRaises(DocumentNotCheckedOut): with self.assertRaises(DocumentNotCheckedOut):
self.document.check_in() self.document.check_in()
def test_auto_checkin(self): def test_auto_check_in(self):
expiration_datetime = now() + datetime.timedelta(seconds=.1) expiration_datetime = now() + datetime.timedelta(seconds=.1)
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True user=self.admin_user, block_new_version=True
) )
@@ -132,7 +132,7 @@ class NewVersionBlockTestCase(DocumentTestMixin, BaseTestCase):
expiration_datetime = now() + datetime.timedelta(days=1) expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document( DocumentCheckout.objects.check_out_document(
document=self.document, expiration_datetime=expiration_datetime, document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True user=self.admin_user, block_new_version=True
) )

View File

@@ -1,23 +1,16 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
import logging import logging
from django.utils.timezone import now
from mayan.apps.common.literals import TIME_DELTA_UNIT_DAYS from mayan.apps.common.literals import TIME_DELTA_UNIT_DAYS
from mayan.apps.documents.tests import GenericDocumentViewTestCase from mayan.apps.documents.tests import GenericDocumentViewTestCase
from mayan.apps.sources.links import link_upload_version from mayan.apps.sources.links import link_upload_version
from mayan.apps.user_management.tests.literals import (
TEST_USER_PASSWORD, TEST_USER_USERNAME, TEST_ADMIN_PASSWORD,
TEST_ADMIN_USERNAME,
)
from ..literals import STATE_CHECKED_OUT, STATE_LABELS from ..literals import STATE_CHECKED_OUT, STATE_LABELS
from ..models import DocumentCheckout from ..models import DocumentCheckout
from ..permissions import ( from ..permissions import (
permission_document_checkin, permission_document_checkin_override, permission_document_check_in, permission_document_check_in_override,
permission_document_checkout, permission_document_checkout_detail_view permission_document_check_out, permission_document_check_out_detail_view
) )
from .mixins import DocumentCheckoutTestMixin from .mixins import DocumentCheckoutTestMixin
@@ -28,55 +21,68 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
super(DocumentCheckoutViewTestCase, self).setUp() super(DocumentCheckoutViewTestCase, self).setUp()
self.login_user() self.login_user()
def _request_document_check_in_view(self): def _request_document_check_in_get_view(self):
return self.get(
viewname='checkouts:check_in_document', args=(self.document.pk,),
)
def test_check_in_document_get_view_no_permission(self):
self._check_out_document()
response = self._request_document_check_in_get_view()
self.assertContains(
response=response, text=self.document.label, status_code=200
)
self.assertTrue(self.document.is_checked_out())
def test_check_in_document_get_view_with_access(self):
self._check_out_document()
self.grant_access(
obj=self.document, permission=permission_document_check_in
)
response = self._request_document_check_in_get_view()
self.assertContains(
response=response, text=self.document.label, status_code=200
)
self.assertTrue(self.document.is_checked_out())
def _request_document_check_in_post_view(self):
return self.post( return self.post(
viewname='checkouts:checkin_document', args=(self.document.pk,), viewname='checkouts:check_in_document', args=(self.document.pk,),
) )
def test_checkin_document_view_no_permission(self): def test_check_in_document_post_view_no_permission(self):
expiration_datetime = now() + datetime.timedelta(days=1) self._check_out_document()
DocumentCheckout.objects.checkout_document( response = self._request_document_check_in_post_view()
document=self.document, expiration_datetime=expiration_datetime,
user=self.user, block_new_version=True
)
self.assertTrue(self.document.is_checked_out())
response = self._request_document_check_in_view()
self.assertEquals(response.status_code, 403) self.assertEquals(response.status_code, 403)
self.assertTrue(self.document.is_checked_out())
def test_checkin_document_view_with_access(self):
expiration_datetime = now() + datetime.timedelta(days=1)
DocumentCheckout.objects.checkout_document(
document=self.document, expiration_datetime=expiration_datetime,
user=self.user, block_new_version=True
)
self.assertTrue(self.document.is_checked_out()) self.assertTrue(self.document.is_checked_out())
def test_check_in_document_post_view_with_access(self):
self._check_out_document()
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_checkin obj=self.document, permission=permission_document_check_in
)
self.grant_access(
obj=self.document,
permission=permission_document_checkout_detail_view
) )
response = self._request_document_check_in_view() response = self._request_document_check_in_post_view()
self.assertEquals(response.status_code, 302) self.assertEquals(response.status_code, 302)
self.assertFalse(self.document.is_checked_out()) self.assertFalse(self.document.is_checked_out())
self.assertFalse( self.assertFalse(
DocumentCheckout.objects.is_document_checked_out( DocumentCheckout.objects.is_checked_out(
document=self.document document=self.document
) )
) )
def _request_document_checkout_view(self): def _request_document_checkout_view(self):
return self.post( return self.post(
viewname='checkouts:checkout_document', args=(self.document.pk,), viewname='checkouts:check_out_document', args=(self.document.pk,),
data={ data={
'expiration_datetime_0': 2, 'expiration_datetime_0': 2,
'expiration_datetime_1': TIME_DELTA_UNIT_DAYS, 'expiration_datetime_1': TIME_DELTA_UNIT_DAYS,
@@ -84,55 +90,57 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
} }
) )
def test_checkout_document_view_no_permission(self): def test_check_out_document_view_no_permission(self):
response = self._request_document_checkout_view() response = self._request_document_checkout_view()
self.assertEquals(response.status_code, 403) self.assertEquals(response.status_code, 403)
self.assertFalse(self.document.is_checked_out()) self.assertFalse(self.document.is_checked_out())
def test_checkout_document_view_with_access(self): def test_check_out_document_view_with_access(self):
self.grant_access( self.grant_access(
obj=self.document, permission=permission_document_checkout obj=self.document, permission=permission_document_check_out
) )
self.grant_access( self.grant_access(
obj=self.document, obj=self.document,
permission=permission_document_checkout_detail_view permission=permission_document_check_out_detail_view
) )
response = self._request_document_checkout_view() response = self._request_document_checkout_view()
self.assertEquals(response.status_code, 302) self.assertEquals(response.status_code, 302)
self.assertTrue(self.document.is_checked_out()) self.assertTrue(self.document.is_checked_out())
def _request_checkout_detail_view(self): def _request_check_out_detail_view(self):
return self.get( return self.get(
viewname='checkouts:checkout_info', args=(self.document.pk,), viewname='checkouts:check_out_info', args=(self.document.pk,),
) )
def test_checkout_detail_view_no_permission(self): def test_checkout_detail_view_no_permission(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
obj=self.document, obj=self.document,
permission=permission_document_checkout permission=permission_document_check_out
) )
response = self._request_checkout_detail_view() response = self._request_check_out_detail_view()
self.assertNotContains( self.assertNotContains(
response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=403 response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=403
) )
def test_checkout_detail_view_with_access(self): def test_checkout_detail_view_with_access(self):
self._checkout_document() self._check_out_document()
self.grant_access( self.grant_access(
obj=self.document, obj=self.document,
permission=permission_document_checkout_detail_view permission=permission_document_check_out_detail_view
) )
response = self._request_checkout_detail_view() response = self._request_check_out_detail_view()
self.assertContains(response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=200) self.assertContains(
response, text=STATE_LABELS[STATE_CHECKED_OUT], status_code=200
)
def test_document_new_version_after_checkout(self): def test_document_new_version_after_check_out(self):
""" """
Gitlab issue #231 Gitlab issue #231
User shown option to upload new version of a document even though it User shown option to upload new version of a document even though it
@@ -142,18 +150,9 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
- Link to upload version view should not resolve - Link to upload version view should not resolve
- Upload version view should reject request - Upload version view should reject request
""" """
self.login( self._check_out_document()
username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD
)
expiration_datetime = now() + datetime.timedelta(days=1) self.login_admin_user()
DocumentCheckout.objects.checkout_document(
document=self.document, expiration_datetime=expiration_datetime,
user=self.admin_user, block_new_version=True
)
self.assertTrue(self.document.is_checked_out())
response = self.post( response = self.post(
'sources:upload_version', args=(self.document.pk,), 'sources:upload_version', args=(self.document.pk,),
@@ -184,30 +183,15 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
# Silence unrelated logging # Silence unrelated logging
logging.getLogger('navigation.classes').setLevel(logging.CRITICAL) logging.getLogger('navigation.classes').setLevel(logging.CRITICAL)
expiration_datetime = now() + datetime.timedelta(days=1) self._check_out_document(user=self.admin_user)
DocumentCheckout.objects.checkout_document( self.grant_access(
document=self.document, expiration_datetime=expiration_datetime, obj=self.document, permission=permission_document_check_in
user=self.admin_user, block_new_version=True
)
self.assertTrue(self.document.is_checked_out())
self.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
self.role.permissions.add(
permission_document_checkin.stored_permission
)
self.role.permissions.add(
permission_document_checkout.stored_permission
) )
response = self.post( response = self.post(
'checkouts:checkin_document', args=(self.document.pk,), follow=True 'checkouts:check_in_document', args=(self.document.pk,)
) )
self.assertContains( self.assertContains(
response, text='Insufficient permissions', status_code=403 response, text='Insufficient permissions', status_code=403
) )
@@ -215,37 +199,18 @@ class DocumentCheckoutViewTestCase(DocumentCheckoutTestMixin, GenericDocumentVie
self.assertTrue(self.document.is_checked_out()) self.assertTrue(self.document.is_checked_out())
def test_forcefull_check_in_document_view_with_permission(self): def test_forcefull_check_in_document_view_with_permission(self):
expiration_datetime = now() + datetime.timedelta(days=1) self._check_out_document(user=self.admin_user)
DocumentCheckout.objects.checkout_document( self.grant_access(
document=self.document, expiration_datetime=expiration_datetime, obj=self.document, permission=permission_document_check_in
user=self.admin_user, block_new_version=True )
self.grant_access(
obj=self.document, permission=permission_document_check_in_override
) )
self.assertTrue(self.document.is_checked_out())
self.login(
username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD
)
self.role.permissions.add(
permission_document_checkin.stored_permission
)
self.role.permissions.add(
permission_document_checkin.stored_permission
)
self.role.permissions.add(
permission_document_checkin_override.stored_permission
)
self.role.permissions.add(
permission_document_checkout_detail_view.stored_permission
)
response = self.post( response = self.post(
'checkouts:checkin_document', args=(self.document.pk,), follow=True 'checkouts:check_in_document', args=(self.document.pk,)
)
self.assertContains(
response, text='hecked in successfully', status_code=200
) )
self.assertEqual(response.status_code, 302)
self.assertFalse(self.document.is_checked_out()) self.assertFalse(self.document.is_checked_out())

View File

@@ -9,18 +9,18 @@ from .views import (
) )
urlpatterns = [ urlpatterns = [
url(r'^list/$', CheckoutListView.as_view(), name='checkout_list'), url(r'^list/$', CheckoutListView.as_view(), name='check_out_list'),
url( url(
r'^(?P<pk>\d+)/check/out/$', CheckoutDocumentView.as_view(), r'^(?P<pk>\d+)/check/out/$', CheckoutDocumentView.as_view(),
name='checkout_document' name='check_out_document'
), ),
url( url(
r'^(?P<pk>\d+)/check/in/$', DocumentCheckinView.as_view(), r'^(?P<pk>\d+)/check/in/$', DocumentCheckinView.as_view(),
name='checkin_document' name='check_in_document'
), ),
url( url(
r'^(?P<pk>\d+)/check/info/$', CheckoutDetailView.as_view(), r'^(?P<pk>\d+)/check/info/$', CheckoutDetailView.as_view(),
name='checkout_info' name='check_out_info'
), ),
] ]

View File

@@ -16,11 +16,11 @@ from mayan.apps.documents.views import DocumentListView
from .exceptions import DocumentAlreadyCheckedOut, DocumentNotCheckedOut from .exceptions import DocumentAlreadyCheckedOut, DocumentNotCheckedOut
from .forms import DocumentCheckoutForm, DocumentCheckoutDefailForm from .forms import DocumentCheckoutForm, DocumentCheckoutDefailForm
from .icons import icon_checkout_info from .icons import icon_check_out_info
from .models import DocumentCheckout from .models import DocumentCheckout
from .permissions import ( from .permissions import (
permission_document_checkin, permission_document_checkin_override, permission_document_check_in, permission_document_check_in_override,
permission_document_checkout, permission_document_checkout_detail_view permission_document_check_out, permission_document_check_out_detail_view
) )
@@ -31,7 +31,7 @@ class CheckoutDocumentView(SingleObjectCreateView):
self.document = get_object_or_404(Document, pk=self.kwargs['pk']) self.document = get_object_or_404(Document, pk=self.kwargs['pk'])
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkout, user=request.user, permissions=permission_document_check_out, user=request.user,
obj=self.document obj=self.document
) )
@@ -47,11 +47,6 @@ class CheckoutDocumentView(SingleObjectCreateView):
instance.save() instance.save()
except DocumentAlreadyCheckedOut: except DocumentAlreadyCheckedOut:
messages.error(self.request, _('Document already checked out.')) messages.error(self.request, _('Document already checked out.'))
except Exception as exception:
messages.error(
self.request,
_('Error trying to check out document; %s') % exception
)
else: else:
messages.success( messages.success(
self.request, self.request,
@@ -67,13 +62,13 @@ class CheckoutDocumentView(SingleObjectCreateView):
} }
def get_post_action_redirect(self): def get_post_action_redirect(self):
return reverse('checkouts:checkout_info', args=(self.document.pk,)) return reverse('checkouts:check_out_info', args=(self.document.pk,))
class CheckoutListView(DocumentListView): class CheckoutListView(DocumentListView):
def get_document_queryset(self): def get_document_queryset(self):
return AccessControlList.objects.filter_by_access( return AccessControlList.objects.filter_by_access(
permission=permission_document_checkout_detail_view, permission=permission_document_check_out_detail_view,
user=self.request.user, user=self.request.user,
queryset=DocumentCheckout.objects.checked_out_documents() queryset=DocumentCheckout.objects.checked_out_documents()
) )
@@ -86,23 +81,23 @@ class CheckoutListView(DocumentListView):
{ {
'name': _('User'), 'name': _('User'),
'attribute': encapsulate( 'attribute': encapsulate(
lambda document: document.checkout_info().user.get_full_name() or document.checkout_info().user lambda document: document.check_out_info().user.get_full_name() or document.check_out_info().user
) )
}, },
{ {
'name': _('Checkout time and date'), 'name': _('Checkout time and date'),
'attribute': encapsulate( 'attribute': encapsulate(
lambda document: document.checkout_info().checkout_datetime lambda document: document.check_out_info().checkout_datetime
) )
}, },
{ {
'name': _('Checkout expiration'), 'name': _('Checkout expiration'),
'attribute': encapsulate( 'attribute': encapsulate(
lambda document: document.checkout_info().expiration_datetime lambda document: document.check_out_info().expiration_datetime
) )
}, },
), ),
'no_results_icon': icon_checkout_info, 'no_results_icon': icon_check_out_info,
'no_results_text': _( 'no_results_text': _(
'Checking out a document blocks certain document ' 'Checking out a document blocks certain document '
'operations for a predetermined amount of ' 'operations for a predetermined amount of '
@@ -118,7 +113,7 @@ class CheckoutListView(DocumentListView):
class CheckoutDetailView(SingleObjectDetailView): class CheckoutDetailView(SingleObjectDetailView):
form_class = DocumentCheckoutDefailForm form_class = DocumentCheckoutDefailForm
model = Document model = Document
object_permission = permission_document_checkout_detail_view object_permission = permission_document_check_out_detail_view
def get_extra_context(self): def get_extra_context(self):
return { return {
@@ -140,7 +135,7 @@ class DocumentCheckinView(ConfirmView):
'object': document, 'object': document,
} }
if document.checkout_info().user != self.request.user: if document.get_check_out_info().user != self.request.user:
context['title'] = _( context['title'] = _(
'You didn\'t originally checked out this document. ' 'You didn\'t originally checked out this document. '
'Forcefully check in the document: %s?' 'Forcefully check in the document: %s?'
@@ -154,19 +149,19 @@ class DocumentCheckinView(ConfirmView):
return get_object_or_404(Document, pk=self.kwargs['pk']) return get_object_or_404(Document, pk=self.kwargs['pk'])
def get_post_action_redirect(self): def get_post_action_redirect(self):
return reverse('checkouts:checkout_info', args=(self.get_object().pk,)) return reverse('checkouts:check_out_info', args=(self.get_object().pk,))
def view_action(self): def view_action(self):
document = self.get_object() document = self.get_object()
if document.checkout_info().user == self.request.user: if document.get_check_out_info().user == self.request.user:
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkin, permissions=permission_document_check_in,
user=self.request.user, obj=document user=self.request.user, obj=document
) )
else: else:
AccessControlList.objects.check_access( AccessControlList.objects.check_access(
permissions=permission_document_checkin_override, permissions=permission_document_check_in_override,
user=self.request.user, obj=document user=self.request.user, obj=document
) )
@@ -176,11 +171,6 @@ class DocumentCheckinView(ConfirmView):
messages.error( messages.error(
self.request, _('Document has not been checked out.') self.request, _('Document has not been checked out.')
) )
except Exception as exception:
messages.error(
self.request,
_('Error trying to check in document; %s') % exception
)
else: else:
messages.success( messages.success(
self.request, self.request,

View File

@@ -11,7 +11,9 @@ class ErrorLogEntryManager(models.Manager):
ErrorLogEntry = apps.get_model( ErrorLogEntry = apps.get_model(
app_label='common', model_name='ErrorLogEntry' app_label='common', model_name='ErrorLogEntry'
) )
model.add_to_class('error_logs', GenericRelation(ErrorLogEntry)) model.add_to_class(
name='error_logs', value=GenericRelation(ErrorLogEntry)
)
class UserLocaleProfileManager(models.Manager): class UserLocaleProfileManager(models.Manager):

View File

@@ -1,13 +1,11 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import timedelta
import logging import logging
from kombu import Exchange, Queue from kombu import Exchange, Queue
from django.apps import apps from django.apps import apps
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls import ModelPermission from mayan.apps.acls import ModelPermission
@@ -16,14 +14,12 @@ from mayan.apps.common import (
menu_tools menu_tools
) )
from mayan.apps.common.classes import ModelField from mayan.apps.common.classes import ModelField
from mayan.apps.common.settings import settings_db_sync_task_delay
from mayan.apps.documents.search import document_search, document_page_search from mayan.apps.documents.search import document_search, document_page_search
from mayan.apps.documents.signals import post_version_upload from mayan.apps.documents.signals import post_version_upload
from mayan.apps.documents.widgets import document_link from mayan.apps.documents.widgets import document_link
from mayan.apps.navigation import SourceColumn from mayan.apps.navigation import SourceColumn
from mayan.celery import app from mayan.celery import app
from .events import event_parsing_document_version_submit
from .handlers import ( from .handlers import (
handler_index_document, handler_initialize_new_parsing_settings, handler_index_document, handler_initialize_new_parsing_settings,
handler_parse_document_version handler_parse_document_version
@@ -35,6 +31,9 @@ from .links import (
link_document_type_parsing_settings, link_document_type_submit, link_document_type_parsing_settings, link_document_type_submit,
link_error_list link_error_list
) )
from .methods import (
method_document_parsing_submit, method_document_version_parsing_submit
)
from .permissions import ( from .permissions import (
permission_content_view, permission_document_type_parsing_setup, permission_content_view, permission_document_type_parsing_setup,
permission_parse_document permission_parse_document
@@ -45,26 +44,6 @@ from .utils import get_document_content
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def document_parsing_submit(self):
latest_version = self.latest_version
# Don't error out if document has no version
if latest_version:
latest_version.submit_for_parsing()
def document_version_parsing_submit(self):
from .tasks import task_parse_document_version
event_parsing_document_version_submit.commit(
action_object=self.document, target=self
)
task_parse_document_version.apply_async(
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
kwargs={'document_version_pk': self.pk},
)
class DocumentParsingApp(MayanAppConfig): class DocumentParsingApp(MayanAppConfig):
app_namespace = 'document_parsing' app_namespace = 'document_parsing'
app_url = 'parsing' app_url = 'parsing'
@@ -95,15 +74,18 @@ class DocumentParsingApp(MayanAppConfig):
model_name='DocumentVersionParseError' model_name='DocumentVersionParseError'
) )
Document.add_to_class('submit_for_parsing', document_parsing_submit)
Document.add_to_class( Document.add_to_class(
'content', get_document_content name='submit_for_parsing', value=method_document_parsing_submit
)
Document.add_to_class(
name='content', value=get_document_content
) )
DocumentVersion.add_to_class( DocumentVersion.add_to_class(
'content', get_document_content name='content', value=get_document_content
) )
DocumentVersion.add_to_class( DocumentVersion.add_to_class(
'submit_for_parsing', document_version_parsing_submit name='submit_for_parsing',
value=method_document_version_parsing_submit
) )
ModelField( ModelField(

View File

@@ -0,0 +1,28 @@
from __future__ import unicode_literals
from datetime import timedelta
from django.utils.timezone import now
from mayan.apps.common.settings import settings_db_sync_task_delay
from .events import event_parsing_document_version_submit
from .tasks import task_parse_document_version
def method_document_parsing_submit(self):
latest_version = self.latest_version
# Don't error out if document has no version
if latest_version:
latest_version.submit_for_parsing()
def method_document_version_parsing_submit(self):
event_parsing_document_version_submit.commit(
action_object=self.document, target=self
)
task_parse_document_version.apply_async(
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
kwargs={'document_version_pk': self.pk},
)

View File

@@ -83,7 +83,7 @@ class DocumentStatesApp(MayanAppConfig):
) )
Document.add_to_class( Document.add_to_class(
'workflow', DocumentStateHelper.constructor name='workflow', value=DocumentStateHelper.constructor
) )
ErrorLogEntry.objects.register(model=WorkflowStateAction) ErrorLogEntry.objects.register(model=WorkflowStateAction)

View File

@@ -90,7 +90,7 @@ class MetadataApp(MayanAppConfig):
MetadataType = self.get_model('MetadataType') MetadataType = self.get_model('MetadataType')
Document.add_to_class( Document.add_to_class(
'metadata_value_of', DocumentMetadataHelper.constructor name='metadata_value_of', value=DocumentMetadataHelper.constructor
) )
ModelAttribute( ModelAttribute(

View File

@@ -1,13 +1,11 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import timedelta
import logging import logging
from kombu import Exchange, Queue from kombu import Exchange, Queue
from django.apps import apps from django.apps import apps
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mayan.apps.acls import ModelPermission from mayan.apps.acls import ModelPermission
@@ -16,14 +14,12 @@ from mayan.apps.common import (
menu_tools menu_tools
) )
from mayan.apps.common.classes import ModelField from mayan.apps.common.classes import ModelField
from mayan.apps.common.settings import settings_db_sync_task_delay
from mayan.apps.documents.search import document_search, document_page_search from mayan.apps.documents.search import document_search, document_page_search
from mayan.apps.documents.signals import post_version_upload from mayan.apps.documents.signals import post_version_upload
from mayan.apps.documents.widgets import document_link from mayan.apps.documents.widgets import document_link
from mayan.apps.navigation import SourceColumn from mayan.apps.navigation import SourceColumn
from mayan.celery import app from mayan.celery import app
from .events import event_ocr_document_version_submit
from .handlers import ( from .handlers import (
handler_index_document, handler_initialize_new_ocr_settings, handler_index_document, handler_initialize_new_ocr_settings,
handler_ocr_document_version, handler_ocr_document_version,
@@ -35,6 +31,9 @@ from .links import (
link_document_type_ocr_settings, link_document_type_submit, link_document_type_ocr_settings, link_document_type_submit,
link_entry_list link_entry_list
) )
from .methods import (
method_document_ocr_submit, method_document_version_ocr_submit
)
from .permissions import ( from .permissions import (
permission_document_type_ocr_setup, permission_ocr_document, permission_document_type_ocr_setup, permission_ocr_document,
permission_ocr_content_view permission_ocr_content_view
@@ -46,26 +45,6 @@ from .utils import get_document_ocr_content
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def document_ocr_submit(self):
latest_version = self.latest_version
# Don't error out if document has no version
if latest_version:
latest_version.submit_for_ocr()
def document_version_ocr_submit(self):
from .tasks import task_do_ocr
event_ocr_document_version_submit.commit(
action_object=self.document, target=self
)
task_do_ocr.apply_async(
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
kwargs={'document_version_pk': self.pk},
)
class OCRApp(MayanAppConfig): class OCRApp(MayanAppConfig):
app_namespace = 'ocr' app_namespace = 'ocr'
app_url = 'ocr' app_url = 'ocr'
@@ -95,12 +74,14 @@ class OCRApp(MayanAppConfig):
DocumentVersionOCRError = self.get_model('DocumentVersionOCRError') DocumentVersionOCRError = self.get_model('DocumentVersionOCRError')
Document.add_to_class('submit_for_ocr', document_ocr_submit) Document.add_to_class(
DocumentVersion.add_to_class( name='submit_for_ocr', value=method_document_ocr_submit
'ocr_content', get_document_ocr_content
) )
DocumentVersion.add_to_class( DocumentVersion.add_to_class(
'submit_for_ocr', document_version_ocr_submit name='ocr_content', value=get_document_ocr_content
)
DocumentVersion.add_to_class(
name='submit_for_ocr', value=method_document_version_ocr_submit
) )
ModelField( ModelField(

28
mayan/apps/ocr/methods.py Normal file
View File

@@ -0,0 +1,28 @@
from __future__ import unicode_literals
from datetime import timedelta
from django.utils.timezone import now
from mayan.apps.common.settings import settings_db_sync_task_delay
from .events import event_ocr_document_version_submit
from .tasks import task_do_ocr
def method_document_ocr_submit(self):
latest_version = self.latest_version
# Don't error out if document has no version
if latest_version:
latest_version.submit_for_ocr()
def method_document_version_ocr_submit(self):
event_ocr_document_version_submit.commit(
action_object=self.document, target=self
)
task_do_ocr.apply_async(
eta=now() + timedelta(seconds=settings_db_sync_task_delay.value),
kwargs={'document_version_pk': self.pk},
)

View File

@@ -31,6 +31,7 @@ from .links import (
link_tag_multiple_delete, link_tag_tagged_item_list link_tag_multiple_delete, link_tag_tagged_item_list
) )
from .menus import menu_tags from .menus import menu_tags
from .methods import method_document_get_tags
from .permissions import ( from .permissions import (
permission_tag_attach, permission_tag_delete, permission_tag_edit, permission_tag_attach, permission_tag_delete, permission_tag_edit,
permission_tag_remove, permission_tag_view permission_tag_remove, permission_tag_view
@@ -65,8 +66,7 @@ class TagsApp(MayanAppConfig):
Tag = self.get_model('Tag') Tag = self.get_model('Tag')
Document.add_to_class( Document.add_to_class(
'attached_tags', name='attached_tags', value=method_document_get_tags
lambda document: DocumentTag.objects.filter(documents=document)
) )
ModelEventType.register( ModelEventType.register(

View File

@@ -0,0 +1,15 @@
from __future__ import unicode_literals
from django.apps import apps
from django.utils.translation import ugettext_lazy as _
def method_document_get_tags(self):
DocumentTag = apps.get_model(app_label='tags', model_name='DocumentTag')
return DocumentTag.objects.filter(documents=self)
method_document_get_tags.help_text = _(
'Return a the tags attached to the document.'
)