Close issue #105, Tie smart links setups to document types
This commit is contained in:
@@ -60,6 +60,7 @@ Migrate existing database schema with::
|
||||
|
||||
$ mayan-edms.py migrate dynamic_search 0001 --fake
|
||||
$ mayan-edms.py migrate history 0001 --fake
|
||||
$ mayan-edms.py migrate linking 0001 --fake
|
||||
$ mayan-edms.py migrate lock_manager 0001 --fake
|
||||
$ mayan-edms.py migrate ocr 0001 --fake
|
||||
$ mayan-edms.py migrate tags 0001 --fake
|
||||
|
||||
@@ -9,16 +9,16 @@ from project_setup.api import register_setup
|
||||
from .links import (smart_link_acl_list, smart_link_create,
|
||||
smart_link_condition_create, smart_link_condition_delete,
|
||||
smart_link_condition_edit, smart_link_condition_list,
|
||||
smart_link_delete, smart_link_edit,
|
||||
smart_link_instances_for_document, smart_link_list,
|
||||
smart_link_setup)
|
||||
smart_link_delete, smart_link_document_types,
|
||||
smart_link_edit, smart_link_instances_for_document,
|
||||
smart_link_list, smart_link_setup)
|
||||
from .models import SmartLink, SmartLinkCondition
|
||||
from .permissions import (PERMISSION_SMART_LINK_DELETE,
|
||||
PERMISSION_SMART_LINK_EDIT,
|
||||
PERMISSION_SMART_LINK_VIEW)
|
||||
|
||||
register_links(Document, [smart_link_instances_for_document], menu_name='form_header')
|
||||
register_links(SmartLink, [smart_link_edit, smart_link_condition_list, smart_link_acl_list, smart_link_delete])
|
||||
register_links(SmartLink, [smart_link_edit, smart_link_document_types, smart_link_condition_list, smart_link_acl_list, smart_link_delete])
|
||||
register_links([SmartLink, 'linking:smart_link_list', 'linking:smart_link_create'], [smart_link_list, smart_link_create], menu_name='secondary_menu')
|
||||
register_links(SmartLinkCondition, [smart_link_condition_edit, smart_link_condition_delete])
|
||||
register_links(['linking:smart_link_condition_list', 'linking:smart_link_condition_create', 'linking:smart_link_condition_edit', 'linking:smart_link_condition_delete'], [smart_link_condition_create], menu_name='sidebar')
|
||||
|
||||
@@ -17,6 +17,7 @@ smart_link_list = {'text': _(u'Smart links'), 'view': 'linking:smart_link_list',
|
||||
smart_link_create = {'text': _(u'Create new smart link'), 'view': 'linking:smart_link_create', 'famfam': 'link_add', 'permissions': [PERMISSION_SMART_LINK_CREATE]}
|
||||
smart_link_edit = {'text': _(u'Edit'), 'view': 'linking:smart_link_edit', 'args': 'object.pk', 'famfam': 'link_edit', 'permissions': [PERMISSION_SMART_LINK_EDIT]}
|
||||
smart_link_delete = {'text': _(u'Delete'), 'view': 'linking:smart_link_delete', 'args': 'object.pk', 'famfam': 'link_delete', 'permissions': [PERMISSION_SMART_LINK_DELETE]}
|
||||
smart_link_document_types = {'text': _('Document types'), 'view': 'linking:smart_link_document_types', 'args': 'object.pk', 'famfam': 'layout', 'permissions': [PERMISSION_SMART_LINK_EDIT]}
|
||||
|
||||
smart_link_condition_list = {'text': _(u'Conditions'), 'view': 'linking:smart_link_condition_list', 'args': 'object.pk', 'famfam': 'cog', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_CREATE]}
|
||||
smart_link_condition_create = {'text': _(u'Create condition'), 'view': 'linking:smart_link_condition_create', 'args': 'object.pk', 'famfam': 'cog_add', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]}
|
||||
|
||||
@@ -20,10 +20,12 @@ class SmartLinkManager(models.Manager):
|
||||
eval_dict['document'] = document
|
||||
eval_dict['metadata'] = MetadataClass(metadata_dict)
|
||||
|
||||
smart_link_qs = self.model.objects.filter(enabled=True)
|
||||
|
||||
if smart_link_obj:
|
||||
smart_link_qs = self.model.objects.filter(Q(enabled=True) & Q(pk=smart_link_obj.pk))
|
||||
else:
|
||||
smart_link_qs = self.model.objects.filter(enabled=True)
|
||||
smart_link_qs= smart_link_qs.filter(pk=smart_link_obj.pk)
|
||||
|
||||
smart_link_qs = smart_link_qs.filter(document_types=document.document_type)
|
||||
|
||||
for smart_link in smart_link_qs:
|
||||
total_query = Q()
|
||||
|
||||
@@ -3,6 +3,8 @@ from __future__ import absolute_import
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from documents.models import DocumentType
|
||||
|
||||
from .literals import INCLUSION_AND, INCLUSION_CHOICES, OPERATOR_CHOICES
|
||||
from .managers import SmartLinkManager
|
||||
|
||||
@@ -11,9 +13,13 @@ class SmartLink(models.Model):
|
||||
title = models.CharField(max_length=96, verbose_name=_(u'Title'))
|
||||
dynamic_title = models.CharField(blank=True, max_length=96, verbose_name=_(u'Dynamic title'), help_text=_(u'This expression will be evaluated against the current selected document. The document metadata is available as variables `metadata` and document properties under the variable `document`.'))
|
||||
enabled = models.BooleanField(default=True, verbose_name=_(u'Enabled'))
|
||||
document_types = models.ManyToManyField(DocumentType, verbose_name=_(u'Document types'))
|
||||
|
||||
objects = SmartLinkManager()
|
||||
|
||||
def get_document_types_not_selected(self):
|
||||
return DocumentType.objects.exclude(pk__in=self.document_types.all())
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
@@ -25,9 +31,9 @@ class SmartLink(models.Model):
|
||||
class SmartLinkCondition(models.Model):
|
||||
smart_link = models.ForeignKey(SmartLink, verbose_name=_(u'Smart link'))
|
||||
inclusion = models.CharField(default=INCLUSION_AND, max_length=16, choices=INCLUSION_CHOICES, help_text=_(u'The inclusion is ignored for the first item.'))
|
||||
foreign_document_data = models.CharField(max_length=32, verbose_name=_(u'Foreign document data'), help_text=_(u'This represents the metadata of all other documents. Available objects: `document.<attribute>` and `metadata.<metadata_type_name>`.'))
|
||||
foreign_document_data = models.CharField(max_length=32, verbose_name=_(u'Foreign document attribute'), help_text=_(u'This represents the metadata of all other documents.'))
|
||||
operator = models.CharField(max_length=16, choices=OPERATOR_CHOICES)
|
||||
expression = models.TextField(verbose_name=_(u'Expression'), help_text=_(u'This expression will be evaluated against the current selected document. The document metadata is available as variables `metadata` and document properties under the variable `document`.'))
|
||||
expression = models.TextField(verbose_name=_(u'Expression'), help_text=_(u'This expression will be evaluated against the current selected document.'))
|
||||
negated = models.BooleanField(default=False, verbose_name=_(u'Negated'), help_text=_(u'Inverts the logic of the operator.'))
|
||||
enabled = models.BooleanField(default=True, verbose_name=_(u'Enabled'))
|
||||
|
||||
|
||||
63
mayan/apps/linking/south_migrations/0001_initial.py
Normal file
63
mayan/apps/linking/south_migrations/0001_initial.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'SmartLink'
|
||||
db.create_table(u'linking_smartlink', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('title', self.gf('django.db.models.fields.CharField')(max_length=96)),
|
||||
('dynamic_title', self.gf('django.db.models.fields.CharField')(max_length=96, blank=True)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
))
|
||||
db.send_create_signal(u'linking', ['SmartLink'])
|
||||
|
||||
# Adding model 'SmartLinkCondition'
|
||||
db.create_table(u'linking_smartlinkcondition', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('smart_link', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['linking.SmartLink'])),
|
||||
('inclusion', self.gf('django.db.models.fields.CharField')(default=u'&', max_length=16)),
|
||||
('foreign_document_data', self.gf('django.db.models.fields.CharField')(max_length=32)),
|
||||
('operator', self.gf('django.db.models.fields.CharField')(max_length=16)),
|
||||
('expression', self.gf('django.db.models.fields.TextField')()),
|
||||
('negated', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
))
|
||||
db.send_create_signal(u'linking', ['SmartLinkCondition'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'SmartLink'
|
||||
db.delete_table(u'linking_smartlink')
|
||||
|
||||
# Deleting model 'SmartLinkCondition'
|
||||
db.delete_table(u'linking_smartlinkcondition')
|
||||
|
||||
|
||||
models = {
|
||||
u'linking.smartlink': {
|
||||
'Meta': {'object_name': 'SmartLink'},
|
||||
'dynamic_title': ('django.db.models.fields.CharField', [], {'max_length': '96', 'blank': 'True'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '96'})
|
||||
},
|
||||
u'linking.smartlinkcondition': {
|
||||
'Meta': {'object_name': 'SmartLinkCondition'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.TextField', [], {}),
|
||||
'foreign_document_data': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inclusion': ('django.db.models.fields.CharField', [], {'default': "u'&'", 'max_length': '16'}),
|
||||
'negated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'operator': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
|
||||
'smart_link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['linking.SmartLink']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['linking']
|
||||
54
mayan/apps/linking/south_migrations/0002_auto.py
Normal file
54
mayan/apps/linking/south_migrations/0002_auto.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding M2M table for field document_types on 'SmartLink'
|
||||
m2m_table_name = db.shorten_name(u'linking_smartlink_document_types')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('smartlink', models.ForeignKey(orm[u'linking.smartlink'], null=False)),
|
||||
('documenttype', models.ForeignKey(orm[u'documents.documenttype'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['smartlink_id', 'documenttype_id'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Removing M2M table for field document_types on 'SmartLink'
|
||||
db.delete_table(db.shorten_name(u'linking_smartlink_document_types'))
|
||||
|
||||
|
||||
models = {
|
||||
u'documents.documenttype': {
|
||||
'Meta': {'ordering': "['name']", 'object_name': 'DocumentType'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}),
|
||||
'ocr': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||
},
|
||||
u'linking.smartlink': {
|
||||
'Meta': {'object_name': 'SmartLink'},
|
||||
'document_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['documents.DocumentType']", 'symmetrical': 'False'}),
|
||||
'dynamic_title': ('django.db.models.fields.CharField', [], {'max_length': '96', 'blank': 'True'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '96'})
|
||||
},
|
||||
u'linking.smartlinkcondition': {
|
||||
'Meta': {'object_name': 'SmartLinkCondition'},
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'expression': ('django.db.models.fields.TextField', [], {}),
|
||||
'foreign_document_data': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inclusion': ('django.db.models.fields.CharField', [], {'default': "u'&'", 'max_length': '16'}),
|
||||
'negated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'operator': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
|
||||
'smart_link': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['linking.SmartLink']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['linking']
|
||||
0
mayan/apps/linking/south_migrations/__init__.py
Normal file
0
mayan/apps/linking/south_migrations/__init__.py
Normal file
@@ -9,6 +9,7 @@ urlpatterns = patterns('linking.views',
|
||||
url(r'^setup/create/$', 'smart_link_create', (), 'smart_link_create'),
|
||||
url(r'^setup/(?P<smart_link_pk>\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'),
|
||||
url(r'^setup/(?P<smart_link_pk>\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'),
|
||||
url(r'^setup/(?P<smart_link_pk>\d+)/document_types/$', 'smart_link_document_types', (), 'smart_link_document_types'),
|
||||
|
||||
url(r'^setup/(?P<smart_link_pk>\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'),
|
||||
url(r'^setup/(?P<smart_link_pk>\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'),
|
||||
|
||||
@@ -13,7 +13,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from acls.models import AccessEntry
|
||||
from acls.utils import apply_default_acls
|
||||
from acls.views import acl_list_for
|
||||
from common.utils import encapsulate
|
||||
from common.utils import encapsulate, generate_choices_w_labels
|
||||
from common.views import assign_remove
|
||||
from common.widgets import two_state_template
|
||||
from documents.models import Document
|
||||
from documents.permissions import PERMISSION_DOCUMENT_VIEW
|
||||
@@ -52,7 +53,7 @@ def smart_link_instance_view(request, document_id, smart_link_pk):
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_SMART_LINK_VIEW, request.user, smart_link)
|
||||
|
||||
object_list, errors = SmartLink.objects.get_smart_link_instances_for(document, smart_link)
|
||||
object_list, errors = SmartLink.objects.get_for(document, smart_link)
|
||||
|
||||
return document_list(
|
||||
request,
|
||||
@@ -69,7 +70,7 @@ def smart_link_instance_view(request, document_id, smart_link_pk):
|
||||
def smart_link_instances_for_document(request, document_id):
|
||||
subtemplates_list = []
|
||||
document = get_object_or_404(Document, pk=document_id)
|
||||
smart_link_instances, errors = SmartLink.objects.get_smart_link_instances_for(document)
|
||||
smart_link_instances, errors = SmartLink.objects.get_for(document)
|
||||
if (request.user.is_staff or request.user.is_superuser) and errors:
|
||||
for error in errors:
|
||||
messages.warning(request, _(u'Smart link query error: %s' % error))
|
||||
@@ -215,6 +216,30 @@ def smart_link_delete(request, smart_link_pk):
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def smart_link_document_types(request, smart_link_pk):
|
||||
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_EDIT])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_SMART_LINK_EDIT, request.user, smart_link)
|
||||
|
||||
return assign_remove(
|
||||
request,
|
||||
left_list=lambda: generate_choices_w_labels(smart_link.get_document_types_not_selected(), display_object_type=False),
|
||||
right_list=lambda: generate_choices_w_labels(smart_link.document_types.all(), display_object_type=False),
|
||||
add_method=lambda x: smart_link.document_types.add(x),
|
||||
remove_method=lambda x: smart_link.document_types.remove(x),
|
||||
#left_list_title=_(u'Document types not in index: %s') % smart_link,
|
||||
#right_list_title=_(u'Document types for index: %s') % smart_link,
|
||||
decode_content_type=True,
|
||||
extra_context={
|
||||
'main_title': _('Document type for which to enable smart link: %s') % smart_link,
|
||||
'object': smart_link,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def smart_link_condition_list(request, smart_link_pk):
|
||||
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
|
||||
|
||||
@@ -244,7 +269,7 @@ def smart_link_condition_create(request, smart_link_pk):
|
||||
AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = SmartLinkConditionForm(request.POST)
|
||||
form = SmartLinkConditionForm(data=request.POST, smart_link=smart_link)
|
||||
if form.is_valid():
|
||||
new_smart_link_condition = form.save(commit=False)
|
||||
new_smart_link_condition.smart_link = smart_link
|
||||
@@ -252,7 +277,7 @@ def smart_link_condition_create(request, smart_link_pk):
|
||||
messages.success(request, _(u'Smart link condition: "%s" created successfully.') % new_smart_link_condition)
|
||||
return HttpResponseRedirect(reverse('linking:smart_link_condition_list', args=[smart_link.pk]))
|
||||
else:
|
||||
form = SmartLinkConditionForm(initial={'smart_link': smart_link})
|
||||
form = SmartLinkConditionForm(smart_link=smart_link)
|
||||
|
||||
return render_to_response('main/generic_form.html', {
|
||||
'form': form,
|
||||
@@ -273,15 +298,13 @@ def smart_link_condition_edit(request, smart_link_condition_pk):
|
||||
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse('main:home'))))
|
||||
|
||||
if request.method == 'POST':
|
||||
form = SmartLinkConditionForm(request.POST, instance=smart_link_condition)
|
||||
form = SmartLinkConditionForm(request.POST, smart_link=smart_link_condition.smart_link, instance=smart_link_condition)
|
||||
if form.is_valid():
|
||||
new_smart_link_condition = form.save(commit=False)
|
||||
new_smart_link_condition.smart_link = smart_link_condition.smart_link
|
||||
new_smart_link_condition.save()
|
||||
messages.success(request, _(u'Smart link condition: "%s" edited successfully.') % new_smart_link_condition)
|
||||
smart_link_condition = form.save()
|
||||
messages.success(request, _(u'Smart link condition: "%s" edited successfully.') % smart_link_condition)
|
||||
return HttpResponseRedirect(next)
|
||||
else:
|
||||
form = SmartLinkConditionForm(instance=smart_link_condition)
|
||||
form = SmartLinkConditionForm(smart_link=smart_link_condition.smart_link, instance=smart_link_condition)
|
||||
|
||||
return render_to_response('main/generic_form.html', {
|
||||
'form': form,
|
||||
|
||||
Reference in New Issue
Block a user