diff options
| -rw-r--r-- | CHANGES.md | 13 | ||||
| -rw-r--r-- | archaeological_context_records/tests.py | 97 | ||||
| -rw-r--r-- | archaeological_finds/models_finds.py | 1 | ||||
| -rw-r--r-- | archaeological_finds/tests.py | 138 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 4 | ||||
| -rw-r--r-- | archaeological_operations/tests.py | 131 | ||||
| -rw-r--r-- | ishtar_common/migrations/0068_auto__add_field_spatialreferencesystem_auth_name.py | 485 | ||||
| -rw-r--r-- | ishtar_common/models.py | 41 | ||||
| -rw-r--r-- | ishtar_common/tests.py | 305 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 1 | ||||
| -rw-r--r-- | ishtar_common/views.py | 4 | ||||
| -rw-r--r-- | version.py | 2 | 
12 files changed, 1161 insertions, 61 deletions
| diff --git a/CHANGES.md b/CHANGES.md index cb0e700c0..02bbd08e2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,19 @@  Ishtar changelog  ================ +0.99.7 (2017-01-30) +------------------- + +### Features ### + +- Spatial ref. system: add auth_name to SRS model +- Improve search tests + +### Bug fixes ### + +- Fix material type search for finds. +- Fix shortcut menu for baskets. +  0.99.6 (2017-01-29)  ------------------- diff --git a/archaeological_context_records/tests.py b/archaeological_context_records/tests.py index fe4bb7674..c56964670 100644 --- a/archaeological_context_records/tests.py +++ b/archaeological_context_records/tests.py @@ -140,6 +140,30 @@ class ContextRecordTest(ContextRecordInit, TestCase):          models.RecordRelations.objects.create(              left_record=cr_1, right_record=cr_2, relation_type=sym_rel_type) +    def testExternalID(self): +        cr = self.context_records[0] +        self.assertEqual( +            cr.external_id, +            u"{}-{}".format(cr.parcel.external_id, cr.label)) + + +class ContextRecordSearchTest(ContextRecordInit, TestCase): +    fixtures = ImportContextRecordTest.fixtures + +    def setUp(self): +        IshtarSiteProfile.objects.create() +        self.username, self.password, self.user = create_superuser() +        self.create_context_record(data={"label": u"CR 1"}) +        self.create_context_record(data={"label": u"CR 2"}) + +        cr_1 = self.context_records[0] +        cr_2 = self.context_records[1] +        sym_rel_type = models.RelationType.objects.filter( +            symmetrical=True).all()[0] +        self.cr_rel_type = sym_rel_type +        models.RecordRelations.objects.create( +            left_record=cr_1, right_record=cr_2, relation_type=sym_rel_type) +      def testSearchExport(self):          c = Client()          response = c.get(reverse('get-contextrecord')) @@ -187,11 +211,76 @@ class ContextRecordTest(ContextRecordInit, TestCase):          lines = [line for line in response.content.split('\n') if line]          self.assertEqual(len(lines), 3) -    def testZExternalID(self): +    def testUnitHierarchicSearch(self):          cr = self.context_records[0] -        self.assertEqual( -            cr.external_id, -            u"{}-{}".format(cr.parcel.external_id, cr.label)) +        c = Client() + +        neg = models.Unit.objects.get(txt_idx='negative') +        dig = models.Unit.objects.get(txt_idx='digging') +        dest = models.Unit.objects.get(txt_idx='partial_destruction') +        cr.unit = (dig) +        cr.save() +        search = {'unit': dig.pk} + +        # no result when no authentication +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) + +        # one result for exact search +        c.login(username=self.username, password=self.password) +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +        # no result for the brother +        search = {'unit': dest.pk} +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 0) + +        # one result for the father +        search = {'unit': neg.pk} +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +    def testPeriodHierarchicSearch(self): +        cr = self.context_records[0] +        c = Client() + +        neo = models.Period.objects.get(txt_idx='neolithic') +        final_neo = models.Period.objects.get(txt_idx='final_neolithic') +        recent_neo = models.Period.objects.get(txt_idx='recent_neolithic') +        dating = models.Dating.objects.create( +            period=final_neo +        ) +        cr.datings.add(dating) + +        search = {'datings__period': final_neo.pk} + +        # no result when no authentication +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) + +        # one result for exact search +        c.login(username=self.username, password=self.password) +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +        # no result for the brother +        search = {'datings__period': recent_neo.pk} +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 0) + +        # one result for the father +        search = {'datings__period': neo.pk} +        response = c.get(reverse('get-contextrecord'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1)  class RecordRelationsTest(ContextRecordInit, TestCase): diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 588edb5cf..651559426 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -382,6 +382,7 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):          'base_finds__context_record__operation__code_patriarche':              'base_finds__context_record__operation__code_patriarche',          'datings__period': 'datings__period__pk', +        'material_types': 'material_types__pk',          'base_finds__find__description':              'base_finds__find__description__icontains',          'base_finds__batch': 'base_finds__batch', diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index 2d1367c58..34f95cf7d 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -17,7 +17,7 @@  # See the file COPYING for details. -import datetime +import json  from django.conf import settings  from django.contrib.auth.models import User @@ -29,7 +29,7 @@ from ishtar_common.models import ImporterType, IshtarUser, ImporterColumn,\      FormaterType, ImportTarget  from ishtar_common.models import Person -from archaeological_context_records.models import Period +from archaeological_context_records.models import Period, Dating  from archaeological_finds import models, views  from archaeological_warehouse.models import Warehouse, WarehouseType @@ -325,6 +325,140 @@ class FindTest(FindInit, TestCase):                        response.content) +class FindSearchTest(FindInit, TestCase): +    fixtures = [settings.ROOT_PATH + +                '../fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../ishtar_common/fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../archaeological_files/fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../archaeological_operations/fixtures/initial_data-fr.json', +                settings.ROOT_PATH + +                '../archaeological_finds/fixtures/initial_data-fr.json', +                ] +    model = models.Find + +    def setUp(self): +        self.create_finds(force=True) +        self.username = 'myuser' +        self.password = 'mypassword' +        User.objects.create_superuser(self.username, 'myemail@test.com', +                                      self.password) +        self.client = Client() + +    def testMaterialTypeHierarchicSearch(self): +        find = self.finds[0] +        c = Client() +        metal = models.MaterialType.objects.get(txt_idx='metal') +        iron_metal = models.MaterialType.objects.get(txt_idx='iron_metal') +        not_iron_metal = models.MaterialType.objects.get( +            txt_idx='not_iron_metal') +        find.material_types.add(iron_metal) + +        search = {'material_types': iron_metal.pk} + +        # no result when no authentication +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) +        c.login(username=self.username, password=self.password) + +        # one result for exact search +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 1) + +        # no result for the brother +        search = {'material_types': not_iron_metal.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 0) + +        # one result for the father +        search = {'material_types': metal.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 1) + +    def testPeriodHierarchicSearch(self): +        find = self.finds[0] +        c = Client() + +        neo = Period.objects.get(txt_idx='neolithic') +        final_neo = Period.objects.get(txt_idx='final_neolithic') +        recent_neo = Period.objects.get(txt_idx='recent_neolithic') +        dating = Dating.objects.create( +            period=final_neo +        ) +        find.datings.add(dating) + +        search = {'datings__period': final_neo.pk} + +        # no result when no authentication +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) + +        # one result for exact search +        c.login(username=self.username, password=self.password) +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +        # no result for the brother +        search = {'datings__period': recent_neo.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 0) + +        # one result for the father +        search = {'datings__period': neo.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +    def testConservatoryStateHierarchicSearch(self): +        find = self.finds[0] +        c = Client() +        cs1 = models.ConservatoryState.objects.all()[0] +        cs1.parent = None +        cs1.save() +        cs2 = models.ConservatoryState.objects.all()[1] +        cs2.parent = cs1 +        cs2.save() +        cs3 = models.ConservatoryState.objects.all()[2] +        cs3.parent = cs1 +        cs3.save() +        find.conservatory_state = cs2 +        find.save() + +        search = {'conservatory_state': cs2.pk} + +        # no result when no authentication +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) +        c.login(username=self.username, password=self.password) + +        # one result for exact search +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 1) + +        # no result for the brother +        search = {'conservatory_state': cs3.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 0) + +        # one result for the father +        search = {'conservatory_state': cs1.pk} +        response = c.get(reverse('get-find'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(json.loads(response.content)['total'] == 1) + +  class PackagingTest(FindInit, TestCase):      fixtures = [settings.ROOT_PATH +                  '../fixtures/initial_data.json', diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 30cd61010..7c9efaef7 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -551,9 +551,9 @@ class Operation(ClosedItem, BaseHistorizedItem, ImageModel, OwnPerms,      @classmethod      def get_query_owns(cls, user): -        return Q(in_charge=user.ishtaruser.person) |\ +        return (Q(in_charge=user.ishtaruser.person) |\              Q(scientist=user.ishtaruser.person) |\ -            Q(history_creator=user) & Q(end_date__isnull=True) +            Q(history_creator=user)) & Q(end_date__isnull=True)      def is_active(self):          return not bool(self.end_date) diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 9a61d8bbb..ba7722d84 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -566,7 +566,73 @@ class OperationTest(TestCase, OperationInitTest):          parcel.save()          self.assertEqual(parcel.external_id, 'blabla') -    def testSearch(self): +    def create_relations(self): +        rel1 = models.RelationType.objects.create( +            symmetrical=True, label='Include', txt_idx='include') +        rel2 = models.RelationType.objects.create( +            symmetrical=False, label='Included', txt_idx='included', +            inverse_relation=rel1) +        models.RecordRelations.objects.create( +            left_record=self.operations[0], +            right_record=self.operations[1], +            relation_type=rel1) +        return rel1, rel2 + +    def testPostDeleteRelations(self): +        self.create_relations() +        self.operations[0].delete() + +    def testPostDeleteParcels(self): +        ope = self.operations[0] +        town = Town.objects.create(name='plouf', numero_insee='20000') +        parcel = models.Parcel.objects.create(town=town) +        parcel_nb = models.Parcel.objects.count() +        ope.parcels.add(parcel) +        ope.delete() +        # our parcel has no operation attached and should be deleted +        self.assertEqual(parcel_nb - 1, models.Parcel.objects.count()) +        ope = self.operations[1] +        parcel = models.Parcel.objects.create(town=town) +        parcel_nb = models.Parcel.objects.count() +        ope.parcels.add(parcel) +        ope.parcels.clear()  # no signal raised... should resave +        models.Parcel.objects.filter(pk=parcel.pk).all()[0].save() +        # our parcel has no operation attached and should be deleted +        self.assertEqual(parcel_nb - 1, models.Parcel.objects.count()) + +    def testIndex(self): +        ope = create_operation(self.user, values={'year': 2042}) +        self.assertEqual(ope.operation_code, 1) +        ope2 = create_operation(self.user, values={'year': 2042}) +        self.assertEqual(ope2.operation_code, 2) +        ope = create_operation(self.user, values={'year': 0}) +        self.assertEqual(ope.operation_code, 1) +        ope2 = create_operation(self.user, values={'year': 0}) +        self.assertEqual(ope2.operation_code, 2) + + +class OperationSearchTest(TestCase, OperationInitTest): +    fixtures = [settings.ROOT_PATH + +                '../fixtures/initial_data-auth-fr.json', +                settings.ROOT_PATH + +                '../ishtar_common/fixtures/initial_data-fr.json', +                settings.ROOT_PATH + +                '../archaeological_files/fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../archaeological_operations/fixtures/initial_data-fr.json'] + +    def setUp(self): +        IshtarSiteProfile.objects.create() +        self.username, self.password, self.user = create_superuser() +        self.alt_username, self.alt_password, self.alt_user = create_user() +        self.alt_user.user_permissions.add(Permission.objects.get( +            codename='view_own_operation')) +        self.orgas = self.create_orgas(self.user) +        self.operations = self.create_operation(self.user, self.orgas[0]) +        self.operations += self.create_operation(self.alt_user, self.orgas[0]) +        self.item = self.operations[0] + +    def testBaseSearch(self):          c = Client()          response = c.get(reverse('get-operation'), {'year': '2010'})          # no result when no authentification @@ -603,27 +669,40 @@ class OperationTest(TestCase, OperationInitTest):          response = c.get(reverse('get-operation'), search)          self.assertTrue(json.loads(response.content)['total'] == 2) -    def testPostDeleteRelations(self): -        self.create_relations() -        self.operations[0].delete() - -    def testPostDeleteParcels(self): -        ope = self.operations[0] -        town = Town.objects.create(name='plouf', numero_insee='20000') -        parcel = models.Parcel.objects.create(town=town) -        parcel_nb = models.Parcel.objects.count() -        ope.parcels.add(parcel) -        ope.delete() -        # our parcel has no operation attached and should be deleted -        self.assertEqual(parcel_nb - 1, models.Parcel.objects.count()) +    def testHierarchicSearch(self):          ope = self.operations[1] -        parcel = models.Parcel.objects.create(town=town) -        parcel_nb = models.Parcel.objects.count() -        ope.parcels.add(parcel) -        ope.parcels.clear()  # no signal raised... should resave -        models.Parcel.objects.filter(pk=parcel.pk).all()[0].save() -        # our parcel has no operation attached and should be deleted -        self.assertEqual(parcel_nb - 1, models.Parcel.objects.count()) +        c = Client() + +        neo = models.Period.objects.get(txt_idx='neolithic') +        final_neo = models.Period.objects.get(txt_idx='final_neolithic') +        recent_neo = models.Period.objects.get(txt_idx='recent_neolithic') +        ope.periods.add(final_neo) + +        search = {'periods': final_neo.pk} + +        # no result when no authentication +        response = c.get(reverse('get-operation'), search) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(not json.loads(response.content)) +        c.login(username=self.username, password=self.password) + +        # one result for exact search +        response = c.get(reverse('get-operation'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) + +        # no result for the brother +        search = {'periods': recent_neo.pk} +        response = c.get(reverse('get-operation'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 0) + +        # one result for the father +        search = {'periods': neo.pk} +        response = c.get(reverse('get-operation'), search) +        self.assertEqual(response.status_code, 200) +        self.assertEqual(json.loads(response.content)['total'], 1) +      def testOwnSearch(self):          c = Client() @@ -638,16 +717,6 @@ class OperationTest(TestCase, OperationInitTest):                           {'operator': self.orgas[0].pk})          self.assertTrue(json.loads(response.content)['total'] == 1) -    def testIndex(self): -        ope = create_operation(self.user, values={'year': 2042}) -        self.assertEqual(ope.operation_code, 1) -        ope2 = create_operation(self.user, values={'year': 2042}) -        self.assertEqual(ope2.operation_code, 2) -        ope = create_operation(self.user, values={'year': 0}) -        self.assertEqual(ope.operation_code, 1) -        ope2 = create_operation(self.user, values={'year': 0}) -        self.assertEqual(ope2.operation_code, 2) -  def create_administrativact(user, operation):      act_type, created = models.ActType.objects.get_or_create( diff --git a/ishtar_common/migrations/0068_auto__add_field_spatialreferencesystem_auth_name.py b/ishtar_common/migrations/0068_auto__add_field_spatialreferencesystem_auth_name.py new file mode 100644 index 000000000..a7f83884d --- /dev/null +++ b/ishtar_common/migrations/0068_auto__add_field_spatialreferencesystem_auth_name.py @@ -0,0 +1,485 @@ +# -*- 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 field 'SpatialReferenceSystem.auth_name' +        db.add_column('ishtar_common_spatialreferencesystem', 'auth_name', +                      self.gf('django.db.models.fields.CharField')(default='EPSG', max_length=256), +                      keep_default=False) + + +    def backwards(self, orm): +        # Deleting field 'SpatialReferenceSystem.auth_name' +        db.delete_column('ishtar_common_spatialreferencesystem', 'auth_name') + + +    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', [], {'related_name': "'author'", 'to': "orm['ishtar_common.Person']"}) +        }, +        'ishtar_common.authortype': { +            'Meta': {'object_name': 'AuthorType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        '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'}), +            'state': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.State']", 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.documenttemplate': { +            'Meta': {'ordering': "['associated_object_name', 'name']", 'object_name': 'DocumentTemplate'}, +            'associated_object_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'template': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}) +        }, +        'ishtar_common.format': { +            'Meta': {'object_name': 'Format'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        'ishtar_common.formatertype': { +            'Meta': {'ordering': "('formater_type', 'options')", 'unique_together': "(('formater_type', 'options', 'many_split'),)", 'object_name': 'FormaterType'}, +            'formater_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'many_split': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'options': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.globalvar': { +            'Meta': {'ordering': "['slug']", 'object_name': 'GlobalVar'}, +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), +            'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) +        }, +        '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'}), +            'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}), +            'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', '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'}), +            'merge_key': ('django.db.models.fields.TextField', [], {'null': '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': '500'}), +            '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'}), +            'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.historicalperson': { +            'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalPerson'}, +            'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}), +            'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}), +            'attached_to_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', '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'}), +            'merge_key': ('django.db.models.fields.TextField', [], {'null': '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': '200', 'null': 'True', 'blank': 'True'}), +            'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), +            'title_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.import': { +            'Meta': {'object_name': 'Import'}, +            'conservative_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}), +            'encoding': ('django.db.models.fields.CharField', [], {'default': "'utf-8'", 'max_length': '15'}), +            'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), +            'error_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), +            'imported_images': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.ImporterType']"}), +            'match_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'seconds_remaining': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'skip_lines': ('django.db.models.fields.IntegerField', [], {'default': '1'}), +            'state': ('django.db.models.fields.CharField', [], {'default': "'C'", 'max_length': '2'}), +            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']"}) +        }, +        'ishtar_common.importercolumn': { +            'Meta': {'ordering': "('importer_type', 'col_number')", 'unique_together': "(('importer_type', 'col_number'),)", 'object_name': 'ImporterColumn'}, +            'col_number': ('django.db.models.fields.IntegerField', [], {'default': '1'}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'columns'", 'to': "orm['ishtar_common.ImporterType']"}), +            'label': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'regexp_pre_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}), +            'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) +        }, +        'ishtar_common.importerdefault': { +            'Meta': {'object_name': 'ImporterDefault'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'defaults'", 'to': "orm['ishtar_common.ImporterType']"}), +            'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}) +        }, +        'ishtar_common.importerdefaultvalues': { +            'Meta': {'object_name': 'ImporterDefaultValues'}, +            'default_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'default_values'", 'to': "orm['ishtar_common.ImporterDefault']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}), +            'value': ('django.db.models.fields.CharField', [], {'max_length': '500'}) +        }, +        'ishtar_common.importerduplicatefield': { +            'Meta': {'object_name': 'ImporterDuplicateField'}, +            'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'duplicate_fields'", 'to': "orm['ishtar_common.ImporterColumn']"}), +            'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}), +            'field_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) +        }, +        'ishtar_common.importertype': { +            'Meta': {'object_name': 'ImporterType'}, +            'associated_models': ('django.db.models.fields.CharField', [], {'max_length': '200'}), +            'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'is_template': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}), +            'unicity_keys': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}), +            'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.importtarget': { +            'Meta': {'object_name': 'ImportTarget'}, +            'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'targets'", 'to': "orm['ishtar_common.ImporterColumn']"}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'concat': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'concat_str': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}), +            'force_new': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'formater_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.FormaterType']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'regexp_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}), +            'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}) +        }, +        'ishtar_common.ishtarsiteprofile': { +            'Meta': {'ordering': "['label']", 'object_name': 'IshtarSiteProfile'}, +            'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'base_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(0, 0, 0, 0)'", 'max_length': '200'}), +            'base_find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{context_record__external_id}-{label}'"}), +            'container_external_id': ('django.db.models.fields.TextField', [], {'default': "'{responsible__external_id}-{index}'"}), +            'context_record': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'context_record_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(210,200,0,0.2)'", 'max_length': '200'}), +            'context_record_external_id': ('django.db.models.fields.TextField', [], {'default': "'{parcel__external_id}-{label}'"}), +            'currency': ('django.db.models.fields.CharField', [], {'default': "u'\\u20ac'", 'max_length': "'5'"}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'file_external_id': ('django.db.models.fields.TextField', [], {'default': "'{year}-{numeric_reference}'"}), +            'files': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'files_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(0, 32, 210, 0.1)'", 'max_length': '200'}), +            'find': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'find_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(210,0,0,0.15)'", 'max_length': '200'}), +            'find_external_id': ('django.db.models.fields.TextField', [], {'default': "'{get_first_base_find__context_record__external_id}-{label}'"}), +            'homepage': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'label': ('django.db.models.fields.TextField', [], {}), +            'mapping': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'mapping_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(72, 236, 0, 0.15)'", 'max_length': '200'}), +            'parcel_external_id': ('django.db.models.fields.TextField', [], {'default': "'{associated_file__external_id}{operation__code_patriarche}-{town__numero_insee}-{section}{parcel_number}'"}), +            'person_raw_name': ('django.db.models.fields.TextField', [], {'default': "'{name|upper} {surname}'"}), +            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), +            'warehouse': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'warehouse_color': ('django.db.models.fields.CharField', [], {'default': "'rgba(10,20,200,0.15)'", 'max_length': '200'}), +            'warehouse_external_id': ('django.db.models.fields.TextField', [], {'default': "'{name|slug}'"}) +        }, +        'ishtar_common.ishtaruser': { +            'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']}, +            'advanced_shortcut_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ishtaruser'", 'unique': 'True', 'to': "orm['ishtar_common.Person']"}), +            'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}) +        }, +        'ishtar_common.itemkey': { +            'Meta': {'object_name': 'ItemKey'}, +            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'importer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}), +            'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) +        }, +        'ishtar_common.operationtype': { +            'Meta': {'ordering': "['-preventive', 'order', 'label']", 'object_name': 'OperationType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), +            'preventive': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) +        }, +        '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'}), +            'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}), +            'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_organization'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}), +            'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}), +            'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}), +            'merge_key': ('django.db.models.fields.TextField', [], {'null': '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': '500'}), +            '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'}), +            'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.organizationtype': { +            'Meta': {'ordering': "('label',)", 'object_name': 'OrganizationType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        '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'}), +            'alt_address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'alt_address_is_prefered': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'alt_country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'alt_postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}), +            'archived': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}), +            'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'members'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['ishtar_common.Organization']"}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'contact_type': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), +            'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_person'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}), +            'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}), +            'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}), +            'merge_key': ('django.db.models.fields.TextField', [], {'null': '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': '200', 'null': 'True', 'blank': 'True'}), +            'old_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            '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'}), +            'phone2': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone3': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}), +            'phone_desc': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc2': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'phone_desc3': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), +            'raw_phone': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'salutation': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), +            'title': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.TitleType']", 'null': 'True', 'blank': 'True'}), +            'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.persontype': { +            'Meta': {'ordering': "('label',)", 'object_name': 'PersonType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.Group']", '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': '100'}) +        }, +        'ishtar_common.regexp': { +            'Meta': {'object_name': 'Regexp'}, +            'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), +            'regexp': ('django.db.models.fields.CharField', [], {'max_length': '500'}) +        }, +        'ishtar_common.sourcetype': { +            'Meta': {'object_name': 'SourceType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        'ishtar_common.spatialreferencesystem': { +            'Meta': {'ordering': "('label',)", 'object_name': 'SpatialReferenceSystem'}, +            'auth_name': ('django.db.models.fields.CharField', [], {'default': "'EPSG'", 'max_length': '256'}), +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}), +            'srid': ('django.db.models.fields.IntegerField', [], {}), +            'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) +        }, +        'ishtar_common.state': { +            'Meta': {'ordering': "['number']", 'object_name': 'State'}, +            '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.supporttype': { +            'Meta': {'object_name': 'SupportType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        'ishtar_common.targetkey': { +            'Meta': {'unique_together': "(('target', 'key', 'associated_user', 'associated_import'),)", 'object_name': 'TargetKey'}, +            'associated_import': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}), +            'associated_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'is_set': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'key': ('django.db.models.fields.TextField', [], {}), +            'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'keys'", 'to': "orm['ishtar_common.ImportTarget']"}), +            'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) +        }, +        'ishtar_common.titletype': { +            'Meta': {'ordering': "('label',)", 'object_name': 'TitleType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            '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': '100'}) +        }, +        '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'}), +            'imports': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'imported_ishtar_common_town'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['ishtar_common.Import']"}), +            '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'}) +        } +    } + +    complete_apps = ['ishtar_common']
\ No newline at end of file diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 7015c70a5..572bd85e7 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -242,13 +242,27 @@ class OwnPerms:      @classmethod      def _return_get_owns(cls, owns, values, get_short_menu_class,                           label_key='cached_label'): +        sorted_values = [] +        if hasattr(cls, 'BASKET_MODEL'): +            owns_len = len(owns) +            for idx, item in enumerate(reversed(owns)): +                if get_short_menu_class: +                    item = item[0] +                if type(item) == cls.BASKET_MODEL: +                    basket = owns.pop(owns_len - idx - 1) +                    sorted_values.append(basket) +            sorted_values = list(reversed(sorted_values))          if not values:              if not get_short_menu_class: -                return sorted(owns, key=lambda x: getattr(x, label_key)) -            return sorted(owns, key=lambda x: getattr(x[0], label_key)) +                return sorted_values + list( +                    sorted(owns, key=lambda x: getattr(x, label_key))) +            return sorted_values + list( +                sorted(owns, key=lambda x: getattr(x[0], label_key)))          if not get_short_menu_class: -            return sorted(owns, key=lambda x: x[label_key]) -        return sorted(owns, key=lambda x: x[0][label_key]) +            return sorted_values + list( +                sorted(owns, key=lambda x: x[label_key])) +        return sorted_values + list( +            sorted(owns, key=lambda x: x[0][label_key]))      @classmethod      def get_owns(cls, user, replace_query={}, limit=None, values=None, @@ -288,7 +302,16 @@ class OwnPerms:                      raise NotImplementedError(                          "Call of get_owns with get_short_menu_class option and"                          " no 'id' in values is not implemented") -                items = [(i, cls.get_short_menu_class(i['id'])) for i in items] +                my_items = [] +                for i in items: +                    if hasattr(cls, 'BASKET_MODEL') and \ +                            type(i) == cls.BASKET_MODEL: +                        dct = dict([(k, getattr(i, k)) for k in values]) +                        my_items.append( +                            (dct, cls.BASKET_MODEL.get_short_menu_class(i.pk))) +                    else: +                        my_items.append((i, cls.get_short_menu_class(i['id']))) +                items = my_items              else:                  items = [(i, cls.get_short_menu_class(i.pk)) for i in items]          return items @@ -672,6 +695,10 @@ class Basket(models.Model):      def __unicode__(self):          return self.label +    @property +    def cached_label(self): +        return unicode(self) +      @classmethod      def get_short_menu_class(cls, pk):          return 'basket' @@ -2977,7 +3004,9 @@ post_delete.connect(post_save_cache, sender=OperationType)  class SpatialReferenceSystem(GeneralType):      order = models.IntegerField(_(u"Order"), default=10) -    srid = models.IntegerField(_(u"SRID")) +    auth_name = models.CharField( +        _(u"Authority name"), default='EPSG', max_length=256) +    srid = models.IntegerField(_(u"Authority SRID"))      class Meta:          verbose_name = _(u"Spatial reference system") diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index cdf6ce330..3273db19b 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -17,8 +17,9 @@  # See the file COPYING for details. -from StringIO import StringIO  from bs4 import BeautifulSoup as Soup +import datetime +from StringIO import StringIO  from django.conf import settings  from django.contrib.auth.models import User @@ -34,6 +35,7 @@ from django.test.client import Client  from django.test.simple import DjangoTestSuiteRunner  from ishtar_common import models +from ishtar_common.utils import post_save_point  """  from django.conf import settings @@ -336,14 +338,29 @@ class MergeTest(TestCase):  class ShortMenuTest(TestCase):      def setUp(self): -        from archaeological_operations.models import OperationType          self.username = 'username666'          self.password = 'dcbqj7xnjkxnjsknx!@%'          self.user = User.objects.create_superuser(              self.username, "nomail@nomail.com", self.password)          self.other_user = User.objects.create_superuser(              'John', "nomail@nomail.com", self.password) -        self.ope_type = OperationType.objects.create() +        profile = models.get_current_profile() +        profile.files = True +        profile.context_record = True +        profile.find = True +        profile.warehouse = True +        profile.save() + +    def _create_ope(self, user=None): +        if not user: +            user = self.other_user +        from archaeological_operations.models import Operation, OperationType +        ope_type = OperationType.objects.create() +        return Operation.objects.create( +            operation_type=ope_type, +            history_modifier=user, +            year=2042, operation_code=54 +        )      def testNotConnected(self):          c = Client() @@ -355,31 +372,25 @@ class ShortMenuTest(TestCase):          # no content because the user owns no object          response = c.get(reverse('shortcut-menu'))          self.assertFalse("shortcut-menu" in response.content) -        from archaeological_operations.models import Operation -        Operation.objects.create( -            operation_type=self.ope_type, -            history_modifier=self.user) +        self._create_ope(user=self.user)          # content is here          response = c.get(reverse('shortcut-menu'))          self.assertTrue("shortcut-menu" in response.content)      def testOperation(self): -        from archaeological_operations.models import Operation          c = Client()          c.login(username=self.username, password=self.password) -        ope = Operation.objects.create( -            operation_type=self.ope_type, -            history_modifier=self.other_user, -            year=2042, operation_code=54 -        ) +        ope = self._create_ope()          # not available at first          response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200)          self.assertFalse(str(ope.cached_label) in response.content)          # available because is the creator          ope.history_creator = self.user          ope.save()          response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200)          self.assertTrue(str(ope.cached_label) in response.content)          # available because is in charge @@ -387,6 +398,7 @@ class ShortMenuTest(TestCase):          ope.in_charge = self.user.ishtaruser.person          ope.save()          response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200)          self.assertTrue(str(ope.cached_label) in response.content)          # available because is the scientist @@ -395,8 +407,248 @@ class ShortMenuTest(TestCase):          ope.scientist = self.user.ishtaruser.person          ope.save()          response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200)          self.assertTrue(str(ope.cached_label) in response.content) +        # end date is reached - no more available +        ope.end_date = datetime.date(1900, 1, 1) +        ope.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(ope.cached_label) in response.content) + +    def testFile(self): +        from archaeological_files.models import File, FileType +        c = Client() +        c.login(username=self.username, password=self.password) +        file_type = FileType.objects.create() +        fle = File.objects.create( +            file_type=file_type, +            history_modifier=self.other_user, +            year=2043, +        ) +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(fle.cached_label) in response.content) + +        # available because is the creator +        fle.history_creator = self.user +        fle.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(fle.cached_label) in response.content) + +        # available because is in charge +        fle.history_creator = self.other_user +        fle.in_charge = self.user.ishtaruser.person +        fle.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(fle.cached_label) in response.content) + +        # end date is reached - no more available +        fle.end_date = datetime.date(1900, 1, 1) +        fle.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(fle.cached_label) in response.content) + +    def _create_cr(self): +        from archaeological_context_records.models import ContextRecord +        from archaeological_operations.models import Parcel +        ope = self._create_ope() +        town = models.Town.objects.create() +        parcel = Parcel.objects.create( +            operation=ope, +            town=town, +            section="AA", +            parcel_number=42 +        ) +        return ContextRecord.objects.create( +            parcel=parcel, +            operation=ope, +            history_modifier=self.other_user, +        ) + +    def testContextRecord(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        cr = self._create_cr() + +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(cr.cached_label) in response.content) + +        # available because is the creator +        cr.history_creator = self.user +        cr.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(cr.cached_label) in response.content) + +        # available because is in charge +        cr.history_creator = self.other_user +        cr.save() +        cr.operation.in_charge = self.user.ishtaruser.person +        cr.operation.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(cr.cached_label) in response.content) + +        # available because is the scientist +        cr.history_creator = self.other_user +        cr.save() +        cr.operation.in_charge = None +        cr.operation.scientist = self.user.ishtaruser.person +        cr.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(cr.cached_label) in response.content) + +    def _create_find(self): +        from archaeological_finds.models import BaseFind, Find +        cr = self._create_cr() +        base_find = BaseFind.objects.create( +            context_record=cr +        ) +        find = Find.objects.create( +            label="Where is my find?" +        ) +        find.base_finds.add(base_find) +        return base_find, find + +    def testFind(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        base_find, find = self._create_find() + +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(find.cached_label) in response.content) + +        # available because is the creator +        find.history_creator = self.user +        find.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(find.cached_label) in response.content) + +        # available because is in charge +        find.history_creator = self.other_user +        find.save() +        base_find.context_record.operation.in_charge = \ +            self.user.ishtaruser.person +        base_find.context_record.operation.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(find.cached_label) in response.content) + +        # available because is the scientist +        find.history_creator = self.other_user +        find.save() +        base_find.context_record.operation.in_charge = None +        base_find.context_record.operation.scientist = \ +            self.user.ishtaruser.person +        base_find.context_record.operation.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(find.cached_label) in response.content) + +    def testBasket(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        from archaeological_finds.models import FindBasket +        basket = FindBasket.objects.create( +            label="My basket", +        ) + +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(basket.label) in response.content) + +        # available because is the owner +        basket.user = self.user.ishtaruser +        basket.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(basket.label) in response.content) + +    def testTreatmentFile(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        from archaeological_finds.models import TreatmentFile, TreatmentFileType +        tf = TreatmentFile.objects.create( +            type=TreatmentFileType.objects.create(), +            year=2050 +        ) + +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(tf.cached_label) in response.content) + +        # available because is the creator +        tf.history_creator = self.user +        tf.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(tf.cached_label) in response.content) + +        # available because is in charge +        tf.history_creator = self.other_user +        tf.in_charge = self.user.ishtaruser.person +        tf.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(tf.cached_label) in response.content) + +        # end date is reached - no more available +        tf.end_date = datetime.date(1900, 1, 1) +        tf.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(tf.cached_label) in response.content) + +    def testTreatment(self): +        c = Client() +        c.login(username=self.username, password=self.password) +        from archaeological_finds.models import Treatment +        treat = Treatment.objects.create( +            label="My treatment", +            year=2052 +        ) + +        # not available at first +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(treat.cached_label) in response.content) + +        # available because is the creator +        treat.history_creator = self.user +        treat.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(treat.cached_label) in response.content) + +        # available because is in charge +        treat.history_creator = self.other_user +        treat.person = self.user.ishtaruser.person +        treat.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertTrue(str(treat.cached_label) in response.content) + +        # end date is reached - no more available +        treat.end_date = datetime.date(1900, 1, 1) +        treat.save() +        response = c.get(reverse('shortcut-menu')) +        self.assertEqual(response.status_code, 200) +        self.assertFalse(str(treat.cached_label) in response.content) +  class ImportTest(TestCase):      def testDeleteRelated(self): @@ -541,3 +793,30 @@ class IshtarBasicTest(TestCase):      def test_status(self):          response = self.client.get(reverse('status'))          self.assertEqual(response.status_code, 200) + + +class GeomaticTest(TestCase): +    def test_post_save_point(self): +        class FakeGeomaticObject(object): +            def __init__(self, x, y, z, spatial_reference_system, point=None, +                         point_2d=None): +                self.x = x +                self.y = y +                self.z = z +                self.spatial_reference_system = spatial_reference_system +                self.point = point +                self.point_2d = point_2d + +            def save(self, *args, **kwargs): +                pass + +        srs = models.SpatialReferenceSystem.objects.create( +            label='WGS84', txt_idx='wgs84', srid=4326 +        ) +        obj = FakeGeomaticObject( +            x=2, y=3, z=4, +            spatial_reference_system=srs) +        self.assertIsNone(obj.point_2d) +        post_save_point(None, instance=obj) +        self.assertIsNotNone(obj.point_2d) +        self.assertIsNotNone(obj.point) diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 60913851e..83534d93a 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -190,6 +190,7 @@ def post_save_point(sender, **kwargs):      point_2d = None      if instance.x and instance.y and \              instance.spatial_reference_system and \ +            instance.spatial_reference_system.auth_name == 'EPSG' and \              instance.spatial_reference_system.srid != 0:          point_2d = convert_coordinates_to_point(              instance.x, instance.y, srid=instance.spatial_reference_system.srid) diff --git a/ishtar_common/views.py b/ishtar_common/views.py index dbbc3d538..b7ef5ea47 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -759,7 +759,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                          if not idx:                              q = Q(**{r: val})                          else: -                            q = q | Q(**{r: val}) +                            q |= Q(**{r: val})                      and_reqs.append(q)                      break                  elif req.endswith(k_hr + '__pk'): @@ -769,7 +769,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],                      for idx in xrange(HIERARCHIC_LEVELS):                          req = req[:-2] + 'parent__pk'                          q = Q(**{req: val}) -                        reqs = reqs | q +                        reqs |= q                      and_reqs.append(reqs)                      break          query = Q(**dct) diff --git a/version.py b/version.py index 8fb7392cc..43f9c5cba 100644 --- a/version.py +++ b/version.py @@ -1,4 +1,4 @@ -VERSION = (0, 99, 6) +VERSION = (0, 99, 7)  def get_version(): | 
