diff options
Diffstat (limited to 'archaeological_operations')
| -rw-r--r-- | archaeological_operations/migrations/0018_archaeologicalsite_top_operation.py | 21 | ||||
| -rw-r--r-- | archaeological_operations/models.py | 52 | ||||
| -rw-r--r-- | archaeological_operations/tests.py | 89 | 
3 files changed, 162 insertions, 0 deletions
| diff --git a/archaeological_operations/migrations/0018_archaeologicalsite_top_operation.py b/archaeological_operations/migrations/0018_archaeologicalsite_top_operation.py new file mode 100644 index 000000000..e27d1389c --- /dev/null +++ b/archaeological_operations/migrations/0018_archaeologicalsite_top_operation.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-02-19 17:24 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0017_archaeologicalsite_towns'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='archaeologicalsite', +            name='top_operation', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.Operation', verbose_name='Top operation'), +        ), +    ] diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 60bdd5f2d..7d0efe34c 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -104,6 +104,9 @@ class ArchaeologicalSite(BaseHistorizedItem):                                       blank=True)      towns = models.ManyToManyField(Town, verbose_name=_(u"Towns"),                                     related_name='sites', blank=True) +    top_operation = models.ForeignKey("Operation", blank=True, null=True, +                                      verbose_name=_(u"Top operation"), +                                      on_delete=models.SET_NULL)      class Meta:          verbose_name = _(u"Archaeological site") @@ -142,6 +145,55 @@ class ArchaeologicalSite(BaseHistorizedItem):          return [u"{} ({})".format(town.name, town.numero_insee) for town in                  self.towns.all()] +    def create_or_update_top_operation(self, create=False): +        """ +        Create a virtual operation to associate with the site. +        A cluster operation is created for site with many operation. +        This cluster operation can be used to attach context records +        which are only attached to the site. +        """ +        if not self.top_operation: +            if not create: +                return +            operation_type, created = OperationType.objects.get_or_create( +                txt_idx='unknown', +                defaults={'label': _(u"Unknown"), 'available': True, +                          'order': 999}) +            name = unicode( +                _(u"Virtual operation of site: {}") +            ).format(self.reference) +            if self.towns.count(): +                name += u' - ' + u", ".join([town.name +                                             for town in self.towns.all()]) +            self.top_operation = Operation.objects.create( +                operation_type=operation_type, +                common_name=name, +                virtual_operation=True +            ) +            self.skip_history_when_saving = True +            self.save() +        current_operations = dict( +            [(ope.pk, ope) +             for ope in self.operations.exclude(pk=self.top_operation.pk).all() +             ] +        ) +        q = RecordRelations.objects.filter( +            left_record=self.top_operation, +            relation_type__txt_idx='has_got' +        ) +        for relation in q.all(): +            if relation.right_record.pk not in current_operations: +                relation.delete() +            else: +                current_operations.pop(relation.right_record.pk) +        rel_type = RelationType.get_cache('has_got') +        for missing in current_operations: +            RecordRelations.objects.create( +                left_record=self.top_operation, +                right_record=current_operations[missing], +                relation_type=rel_type +            ) +  def get_values_town_related(item, prefix, values):      values[prefix + 'parcellist'] = item.render_parcels() diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 947be204e..8fe1d8850 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -1926,3 +1926,92 @@ class OperationSourceWizardModificationTest(WizardTest, OperationInitTest,      def post_wizard(self):          source = models.OperationSource.objects.get(pk=self.source.pk)          self.assertEqual(source.authors.count(), 0) + + +class SiteTest(TestCase, OperationInitTest): +    fixtures = FILE_FIXTURES + +    def setUp(self): +        IshtarSiteProfile.objects.get_or_create( +            slug='default', active=True) +        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) + +    def test_create_or_update_top_operation(self): +        operation_0 = self.create_operation(self.user, self.orgas[0])[0] +        operation_1 = self.create_operation(self.alt_user, self.orgas[0])[1] +        site = models.ArchaeologicalSite.objects.create( +            reference="ref-site" +        ) +        site.create_or_update_top_operation() +        q = models.ArchaeologicalSite.objects.filter(reference='ref-site') +        site = q.all()[0] +        # creation not forced - no creation +        self.assertIsNone(site.top_operation) + +        site.create_or_update_top_operation(create=True) +        site = q.all()[0] +        # a default operation has been created +        self.assertIsNotNone(site.top_operation) +        self.assertTrue(site.top_operation.virtual_operation) +        self.assertEqual(site.top_operation.right_relations.count(), 0) + +        # create with one operation attached +        site.top_operation.delete() +        site = q.all()[0] +        site.operations.add(operation_0) +        site.create_or_update_top_operation(create=True) +        site = q.all()[0] +        self.assertIsNotNone(site.top_operation) +        self.assertTrue(site.top_operation.virtual_operation) +        self.assertEqual(site.top_operation.right_relations.count(), 1) +        self.assertEqual( +            site.top_operation.right_relations.all()[0].right_record, +            operation_0 +        ) + +        # create with two operations attached +        site.top_operation.delete() +        site = q.all()[0] +        site.operations.add(operation_0) +        site.operations.add(operation_1) +        site.create_or_update_top_operation(create=True) +        site = q.all()[0] +        self.assertIsNotNone(site.top_operation) +        self.assertTrue(site.top_operation.virtual_operation) +        self.assertEqual(site.top_operation.right_relations.count(), 2) +        attached = [ +            rel.right_record +            for rel in site.top_operation.right_relations.all() +        ] +        self.assertIn(operation_0, attached) +        self.assertIn(operation_1, attached) + +        # detach one operation +        site.operations.remove(operation_1) +        site.create_or_update_top_operation() +        site = q.all()[0] +        self.assertIsNotNone(site.top_operation) +        self.assertTrue(site.top_operation.virtual_operation) +        self.assertEqual(site.top_operation.right_relations.count(), 1) +        self.assertEqual( +            site.top_operation.right_relations.all()[0].right_record, +            operation_0 +        ) + +        # reattach it +        site.operations.add(operation_1) +        site.create_or_update_top_operation() +        site = q.all()[0] +        self.assertIsNotNone(site.top_operation) +        self.assertTrue(site.top_operation.virtual_operation) +        self.assertEqual(site.top_operation.right_relations.count(), 2) +        attached = [ +            rel.right_record +            for rel in site.top_operation.right_relations.all() +        ] +        self.assertIn(operation_0, attached) +        self.assertIn(operation_1, attached) | 
