diff options
-rw-r--r-- | archaeological_files/forms.py | 2 | ||||
-rw-r--r-- | archaeological_files/views.py | 9 | ||||
-rw-r--r-- | archaeological_operations/import_from_csv.py | 12 | ||||
-rw-r--r-- | archaeological_operations/views.py | 7 | ||||
-rw-r--r-- | ishtar_common/admin.py | 4 | ||||
-rw-r--r-- | ishtar_common/backend.py | 5 | ||||
-rw-r--r-- | ishtar_common/forms_common.py | 43 | ||||
-rw-r--r-- | ishtar_common/menu_base.py | 6 | ||||
-rw-r--r-- | ishtar_common/migrations/0003_auto__del_field_person_person_type.py | 209 | ||||
-rw-r--r-- | ishtar_common/models.py | 45 | ||||
-rw-r--r-- | ishtar_common/templates/ishtar/dashboards/dashboard_main.html | 2 | ||||
-rw-r--r-- | ishtar_common/views.py | 27 | ||||
-rw-r--r-- | ishtar_common/widgets.py | 4 |
13 files changed, 297 insertions, 78 deletions
diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 27617f8ad..544c89048 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -46,7 +46,7 @@ from ishtar_common import widgets class FileSelect(TableSelect): towns = get_town_field() in_charge = get_person_field(label=_(u"Person in charge"), - person_type='sra_agent') + person_types=['sra_agent']) file_type = forms.ChoiceField(label=_("File type"), choices=[]) saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[]) year = forms.IntegerField(label=_("Year")) diff --git a/archaeological_files/views.py b/archaeological_files/views.py index 1919d8b62..cda076cd9 100644 --- a/archaeological_files/views.py +++ b/archaeological_files/views.py @@ -35,11 +35,10 @@ from archaeological_operations.forms import ParcelFormSet from forms import * def autocomplete_file(request): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_common.view_file', models.File) and \ - not request.user.has_perm('ishtar_common.view_own_file', models.File) - and not person_types.rights.filter(wizard__url_name='file_search' - ).count()): + person_types = person.person_type + if not request.user.has_perm('ishtar_common.view_file', models.File) and \ + not request.user.has_perm('ishtar_common.view_own_file', models.File) \ + and not request.user.ishtaruser.has_right('file_search'): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') diff --git a/archaeological_operations/import_from_csv.py b/archaeological_operations/import_from_csv.py index ff3bd11f4..1176aec4c 100644 --- a/archaeological_operations/import_from_csv.py +++ b/archaeological_operations/import_from_csv.py @@ -305,11 +305,11 @@ def parse_name_surname(value): return q.all()[0] else: defaults = {'history_modifier':DEFAULT_PERSON, - 'title':'', - 'person_type':PersonType.objects.get( - txt_idx='head_scientist')} + 'title':''} defaults.update(values) p = Person.objects.create(**defaults) + p.person_types.add(PersonType.objects.get( + txt_idx='head_scientist')) return p def parse_person(surname, name, old_ref, owner): @@ -323,11 +323,11 @@ def parse_person(surname, name, old_ref, owner): return q.all()[0] else: defaults = {'history_modifier':owner, - 'title':'', - 'person_type':PersonType.objects.get( - txt_idx='head_scientist')} + 'title':''} defaults.update(values) p = Person.objects.create(**defaults) + p.person_types.add(PersonType.objects.get( + txt_idx='head_scientist')) return p def parse_comment_addr_nature(nature, addr, owner): diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index c2e0b135c..97446b635 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -31,13 +31,11 @@ from forms import * import models def autocomplete_patriarche(request, non_closed=True): - person_types = request.user.ishtaruser.person.person_type if (not request.user.has_perm('ishtar_common.view_operation', models.Operation) and not request.user.has_perm('ishtar_common.view_own_operation', models.Operation) - and not person_types.rights.filter( - wizard__url_name='operation_search').count()): + and not request.user.ishtaruser.has_right('operation_search')): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') @@ -60,8 +58,7 @@ def autocomplete_operation(request, non_closed=True): models.Operation) and not request.user.has_perm('ishtar_common.view_own_operation', models.Operation) - and not person_types.rights.filter( - wizard__url_name='operation_search').count()): + and not request.user.ishtaruser.has_right('operation_search')): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index b470f8223..fdff516f9 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -50,8 +50,8 @@ class OrganizationAdmin(HistorizedObjectAdmin): admin.site.register(models.Organization, OrganizationAdmin) class PersonAdmin(HistorizedObjectAdmin): - list_display = ('name', 'surname', 'email', 'person_type') - list_filter = ("person_type",) + list_display = ('name', 'surname', 'email') + list_filter = ("person_types",) search_fields = ('name', 'surname', 'email',) model = models.Person diff --git a/ishtar_common/backend.py b/ishtar_common/backend.py index f50edd708..297c96180 100644 --- a/ishtar_common/backend.py +++ b/ishtar_common/backend.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2010-2011 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2010-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -50,8 +50,7 @@ class ObjectOwnPermBackend(object): assert perm.split('.')[-1].split('_')[1] == 'own' except (IndexError, AssertionError): return False - if ishtar_user.person.person_type \ - == models.PersonType.objects.get(txt_idx="administrator"): + if ishtar_user.has_right('administrator'): return True if obj is None: model_name = perm.split('_')[-1].capitalize() diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 5078ffaae..db406aaa9 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -53,14 +53,15 @@ def get_town_field(label=_(u"Town"), required=True): validators=[models.valid_id(models.Town)], label=label, help_text=mark_safe(help_text), required=required) -def get_person_field(label=_(u"Person"), required=True, person_type=None): +def get_person_field(label=_(u"Person"), required=True, person_types=[]): # !FIXME hard_link, reverse_lazy doen't seem to work with formsets widget = None url = "/" + settings.URL_PATH + 'autocomplete-person' - if person_type: - if isinstance(person_type, unicode) or isinstance(person_type, str): - person_type = models.PersonType.objects.get(txt_idx=person_type) - url += u"/" + unicode(person_type.pk) + if person_types: + person_types = [ + unicode(models.PersonType.objects.get(txt_idx=person_type).pk) + for person_type in person_types] + url += u"/" + u'_'.join(person_types) widget = widgets.JQueryAutoComplete(url, associated_model=models.Person) return forms.IntegerField(widget=widget, label=label, required=required, validators=[models.valid_id(models.Person)]) @@ -110,8 +111,7 @@ class PersonFormSelection(forms.Form): class PersonForm(forms.Form): form_label = _("Identity") - associated_models = {'attached_to':models.Organization, - 'person_type':models.PersonType} + associated_models = {'attached_to':models.Organization} title = forms.ChoiceField(label=_("Title"), choices=models.Person.TYPE) surname = forms.CharField(label=_(u"Surname"), max_length=20, validators=[name_validator]) @@ -119,23 +119,15 @@ class PersonForm(forms.Form): validators=[name_validator]) email = forms.CharField(label=_(u"Email"), max_length=40, required=False, validators=[validators.validate_email]) - person_type = forms.ChoiceField(label=_("Person type"), - choices=[]) attached_to = forms.IntegerField(label=_("Current organization"), - widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-organization'), - associated_model=models.Organization, new=True), - validators=[models.valid_id(models.Organization)], required=False) - - def __init__(self, *args, **kwargs): - super(PersonForm, self).__init__(*args, **kwargs) - self.fields['person_type'].choices = models.PersonType.get_types() - self.fields['person_type'].help_text = models.PersonType.get_help() + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-organization'), + associated_model=models.Organization, new=True), + validators=[models.valid_id(models.Organization)], required=False) def save(self, user): dct = self.cleaned_data dct['history_modifier'] = user - dct['person_type'] = models.PersonType.objects.get( - pk=dct['person_type']) if 'attached_to' in dct and dct['attached_to']: dct['attached_to'] = models.Organization.objects.get( pk=dct['attached_to']) @@ -143,6 +135,19 @@ class PersonForm(forms.Form): new_item.save() return new_item +class PersonTypeForm(forms.Form): + form_label = _("Person type") + base_model = 'person_type' + associated_models = {'person_type':models.PersonType} + person_type = forms.MultipleChoiceField(label=_("Person type"), + choices=[], widget=forms.CheckboxSelectMultiple) + + def __init__(self, *args, **kwargs): + super(PersonTypeForm, self).__init__(*args, **kwargs) + self.fields['person_type'].choices = models.PersonType.get_types( + empty_first=False) + self.fields['person_type'].help_text = models.PersonType.get_help() + class AccountForm(forms.Form): form_label = _("Account") associated_models = {'pk':models.Person} diff --git a/ishtar_common/menu_base.py b/ishtar_common/menu_base.py index 37f482219..11ce4e688 100644 --- a/ishtar_common/menu_base.py +++ b/ishtar_common/menu_base.py @@ -62,8 +62,7 @@ class MenuItem: return True # manage by person type if hasattr(user, 'ishtaruser'): - person_type = user.ishtaruser.person.person_type - if person_type.rights.filter(wizard__url_name=self.idx).count(): + if ishtar_user.has_right(self.idx): return True return False @@ -76,8 +75,7 @@ class MenuItem: return True # manage by person type if hasattr(user, 'ishtaruser'): - person_type = user.ishtaruser.person.person_type - if person_type.rights.filter(wizard__url_name=self.idx).count(): + if ishtar_user.has_right(self.idx): return True return False diff --git a/ishtar_common/migrations/0003_auto__del_field_person_person_type.py b/ishtar_common/migrations/0003_auto__del_field_person_person_type.py new file mode 100644 index 000000000..369568ecc --- /dev/null +++ b/ishtar_common/migrations/0003_auto__del_field_person_person_type.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +import 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 person_types on 'Person' + db.create_table('ishtar_common_person_person_types', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('person', models.ForeignKey(orm['ishtar_common.person'], null=False)), + ('persontype', models.ForeignKey(orm['ishtar_common.persontype'], null=False)) + )) + db.create_unique('ishtar_common_person_person_types', ['person_id', 'persontype_id']) + + db.execute( + 'insert into ishtar_common_person_person_types (person_id, '\ + 'persontype_id) '\ + 'select id, person_type_id from ishtar_common_person') + # Deleting field 'Person.person_type' + db.delete_column('ishtar_common_person', 'person_type_id') + + + + def backwards(self, orm): + # User chose to not deal with backwards NULL issues for 'Person.person_type' + raise RuntimeError("Cannot reverse this migration. 'Person.person_type' and its values cannot be restored.") + # Removing M2M table for field person_types on 'Person' + db.delete_table('ishtar_common_person_person_types') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'ishtar_common.arrondissement': { + 'Meta': {'object_name': 'Arrondissement'}, + 'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}) + }, + 'ishtar_common.author': { + 'Meta': {'object_name': 'Author'}, + 'author_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AuthorType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Person']"}) + }, + 'ishtar_common.authortype': { + 'Meta': {'object_name': 'AuthorType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'ishtar_common.canton': { + 'Meta': {'object_name': 'Canton'}, + 'arrondissement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Arrondissement']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}) + }, + 'ishtar_common.department': { + 'Meta': {'ordering': "['number']", 'object_name': 'Department'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}), + 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'}) + }, + 'ishtar_common.historicalorganization': { + 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalOrganization'}, + 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'organization_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'town': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}) + }, + 'ishtar_common.ishtaruser': { + 'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']}, + 'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Person']", 'unique': 'True'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'ishtar_common.organization': { + 'Meta': {'object_name': 'Organization'}, + 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'organization_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.OrganizationType']"}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'town': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}) + }, + 'ishtar_common.organizationtype': { + 'Meta': {'object_name': 'OrganizationType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'ishtar_common.person': { + 'Meta': {'object_name': 'Person'}, + 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Organization']", 'null': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'}), + 'person_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.PersonType']", 'symmetrical': 'False'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), + 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'surname': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'town': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}) + }, + 'ishtar_common.persontype': { + 'Meta': {'object_name': 'PersonType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'rights': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.WizardStep']", 'symmetrical': 'False'}), + 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'ishtar_common.sourcetype': { + 'Meta': {'object_name': 'SourceType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'ishtar_common.town': { + 'Meta': {'ordering': "['numero_insee']", 'object_name': 'Town'}, + 'canton': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Canton']", 'null': 'True', 'blank': 'True'}), + 'center': ('django.contrib.gis.db.models.fields.PointField', [], {'srid': '27572', 'null': 'True', 'blank': 'True'}), + 'departement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']", 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'numero_insee': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}), + 'surface': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'ishtar_common.wizard': { + 'Meta': {'ordering': "['url_name']", 'object_name': 'Wizard'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'url_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) + }, + 'ishtar_common.wizardstep': { + 'Meta': {'ordering': "['wizard', 'order']", 'object_name': 'WizardStep'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'order': ('django.db.models.fields.IntegerField', [], {}), + 'url_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'wizard': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Wizard']"}) + } + } + + complete_apps = ['ishtar_common'] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 0155896f4..12b1b79f9 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -47,10 +47,9 @@ def post_save_user(sender, **kwargs): else: ishtaruser = q.all()[0] if ishtaruser.is_superuser \ - and ishtaruser.person.person_type.txt_idx != 'administrator': - ishtaruser.person.person_type = PersonType.objects.get( - txt_idx='administrator') - ishtaruser.person.save() + and not ishtaruser.has_right('administrator'): + ishtaruser.person.person_types.add(PersonType.objects.get( + txt_idx='administrator')) post_save.connect(post_save_user, sender=User) # HistoricalRecords enhancement: don't save identical versions @@ -193,16 +192,18 @@ class GeneralType(models.Model): return u"" @classmethod - def get_types(cls, dct={}, instances=False, exclude=[]): + def get_types(cls, dct={}, instances=False, exclude=[], empty_first=True): base_dct = dct.copy() if hasattr(cls, 'parent'): - return cls._get_parent_types(base_dct, instances, exclude=exclude) - return cls._get_types(base_dct, instances, exclude=exclude) + return cls._get_parent_types(base_dct, instances, exclude=exclude, + empty_first=empty_first) + return cls._get_types(base_dct, instances, exclude=exclude, + empty_first=empty_first) @classmethod - def _get_types(cls, dct={}, instances=False, exclude=[]): + def _get_types(cls, dct={}, instances=False, exclude=[], empty_first=True): dct['available'] = True - if not instances: + if not instances and empty_first: yield ('', '--') items = cls.objects.filter(**dct) if exclude: @@ -237,9 +238,10 @@ class GeneralType(models.Model): yield sub_child @classmethod - def _get_parent_types(cls, dct={}, instances=False, exclude=[]): + def _get_parent_types(cls, dct={}, instances=False, exclude=[], + empty_first=True): dct['available'] = True - if not instances: + if not instances and empty_first: yield ('', '--') dct['parent'] = None items = cls.objects.filter(**dct) @@ -395,10 +397,10 @@ class WizardStep(models.Model): class UserDashboard: def __init__(self): - types = IshtarUser.objects.values('person__person_type', - 'person__person_type__label') + types = IshtarUser.objects.values('person__person_types', + 'person__person_types__label') self.types = types.annotate(number=Count('pk'))\ - .order_by('person__person_type') + .order_by('person__person_types') class Dashboard: def __init__(self, model): @@ -563,7 +565,7 @@ class Person(Address, OwnPerms) : null=True) name = models.CharField(_(u"Name"), max_length=30) email = models.CharField(_(u"Email"), max_length=40, blank=True, null=True) - person_type = models.ForeignKey(PersonType, verbose_name=_(u"Type")) + person_types = models.ManyToManyField(PersonType, verbose_name=_(u"Types")) attached_to = models.ForeignKey('Organization', verbose_name=_(u"Is attached to"), blank=True, null=True) @@ -584,6 +586,14 @@ class Person(Address, OwnPerms) : if getattr(self, attr)] return u" ".join(values) + def has_right(self, right_name): + if type(right_name) in (list, tuple): + return bool( + self.person_types.filter(txt_idx__in=right_name).count() or + self.person_types.filter(wizard__url_name__in=right_name).count()) + return bool(self.person_types.filter(txt_idx=right_name).count() or + self.person_types.filter(wizard__url_name=right_name).count()) + def full_label(self): values = [] if self.title: @@ -613,10 +623,13 @@ class IshtarUser(User): person_type = PersonType.objects.get(txt_idx='public_access') person = Person.objects.create(title='Mr', surname=surname, name=name, email=email, - person_type=person_type, history_modifier=user) + person.person_types.add(person_type) return IshtarUser.objects.create(user_ptr=user, person=person) + def has_right(self, right_name): + return self.person.has_right('administrator') + class AuthorType(GeneralType): class Meta: verbose_name = _(u"Author type") diff --git a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html index e710dbe16..a573a71c6 100644 --- a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html +++ b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html @@ -72,7 +72,7 @@ <tr><th>{% trans "User type" %}</th><th>{% trans "Number" %}</th></tr> {% for user_type in ishtar_users.types %} <tr> - <td class='string'>{{user_type.person__person_type__label}}</td> + <td class='string'>{{user_type.person.person_types.all.0.label}}{#TODO: Display all#}</td> <td>{{user_type.number}}</td> </tr> {% endfor%} diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 346edc0d7..54d2e26a0 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -51,8 +51,9 @@ if settings.XHTML2ODT_PATH: from menus import menu from ishtar_common.forms import FinalForm -from ishtar_common.forms_common import PersonForm, PersonFormSelection,\ - AccountForm, FinalAccountForm, OrganizationForm, AuthorForm +from ishtar_common.forms_common import PersonForm, PersonTypeForm, \ + PersonFormSelection, AccountForm, FinalAccountForm, OrganizationForm, \ + AuthorForm from ishtar_common.wizards import PersonWizard, PersonModifWizard, AccountWizard import models @@ -75,6 +76,7 @@ def index(request): person_creation_wizard = PersonWizard.as_view([ ('identity-person_creation', PersonForm), + ('person_type-person_creation', PersonTypeForm), ('final-person_creation', FinalForm)], label=_(u"New person"), url_name='person_creation') @@ -82,6 +84,7 @@ person_creation_wizard = PersonWizard.as_view([ person_modification_wizard = PersonModifWizard.as_view([ ('selec-person_modification', PersonFormSelection), ('identity-person_modification', PersonForm), + ('person_type-person_creation', PersonTypeForm), ('final-person_modification', FinalForm)], label=_(u"Person modification"), url_name='person_modification') @@ -108,12 +111,10 @@ def check_permission(request, action_slug, obj_id=None): return menu.items[action_slug].is_available(request.user, obj_id) return menu.items[action_slug].can_be_available(request.user) -def autocomplete_person(request, person_type=None): - person_types = request.user.ishtaruser.person.person_type - if (not request.user.has_perm('ishtar_common.view_person', models.Person) and - not request.user.has_perm('ishtar_common.view_own_person', models.Person) - and not person_types.rights.filter(wizard__url_name='person_search' - ).count()): +def autocomplete_person(request, person_types=None): + if not request.user.has_perm('ishtar_common.view_person', models.Person) and \ + not request.user.has_perm('ishtar_common.view_own_person', models.Person) \ + and not request.user.ishtaruser.has_right('person_search'): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') @@ -127,11 +128,11 @@ def autocomplete_person(request, person_type=None): for q in q.split(' '): query = query & (Q(name__icontains=q) | Q(surname__icontains=q) | \ Q(email__icontains=q)) - if person_type: + if person_types: try: - typs = [int(tp) for tp in person_type.split('_') if tp] + typs = [int(tp) for tp in person_types.split('_') if tp] typ = models.PersonType.objects.filter(pk__in=typs).all() - query = query & Q(person_type__in=typ) + query = query & Q(person_types__in=typ) except (ValueError, ObjectDoesNotExist): pass limit = 20 @@ -465,13 +466,11 @@ def revert_item(model): return func def autocomplete_organization(request, orga_type=None): - person_types = request.user.ishtaruser.person.person_type if (not request.user.has_perm('ishtar_common.view_organization', models.Organization) and \ not request.user.has_perm('ishtar_common.view_own_organization', models.Organization) - and not person_types.rights.filter(wizard__url_name='person_search' - ).count()): + and not request.user.ishtaruser.has_right('person_search')): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py index 157151413..82c0c0ac0 100644 --- a/ishtar_common/widgets.py +++ b/ishtar_common/widgets.py @@ -155,8 +155,8 @@ class JQueryAutoComplete(forms.TextInput): attrs_select['value'] = val
if self.associated_model:
try:
- attrs_select['value'] = unicode(self.associated_model.\
-objects.get(pk=value))
+ attrs_select['value'] = unicode(
+ self.associated_model.objects.get(pk=value))
except:
attrs_select['value'] = ""
if not self.attrs.has_key('id'):
|