diff options
| -rw-r--r-- | archaeological_warehouse/models.py | 19 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 18 | 
2 files changed, 36 insertions, 1 deletions
| diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index a72d5a214..add786012 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -1274,6 +1274,22 @@ class Container(      def _get_base_image_path(self):          return self.location._get_base_image_path() + "/" + self.external_id +    def _prevent_parent_infinite_loop(self) -> bool: +        """ +        Check there is no infinite loop in parents. If a loop is detected, set the +        parent to null. +        :return: True if parent has been changed +        """ +        parent = self.parent +        parents = [] +        while parent: +            if parent.id in parents: +                self.parent = None  # break the loop arbitrary +                return True +            parents.append(parent.id) +            parent = parent.parent +        return False +      @classmethod      def _change_child_location(cls, parent):          for child in ( @@ -1742,9 +1758,10 @@ class Container(          self.pre_save()          super(Container, self).save(*args, **kwargs)          self._change_child_location(self) +        updated = False +        updated += self._prevent_parent_infinite_loop()          self._update_warehouse_max_division() -        updated = False          updated += self._calculate_weight()          if not self.index and not self.container_type.stationary: diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index 347382e75..4e6ca9dd9 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -1142,6 +1142,24 @@ class ContainerTest(FindInit, TestCase):              "|".join(sorted([mat0.code, mat1.code, mat2.code])),          ) +    def test_prevent_parent_infinite_loop(self): +        ct = models.ContainerType.objects.all()[0] +        container_1 = models.Container.objects.create( +            reference="Test 1", location=self.main_warehouse, container_type=ct +        ) +        container_2 = models.Container.objects.create( +            reference="Test 2", location=self.main_warehouse, container_type=ct, +            parent=container_1 +        ) +        container_3 = models.Container.objects.create( +            reference="Test 2", location=self.main_warehouse, container_type=ct, +            parent=container_2 +        ) +        container_1.parent = container_3 +        container_1.save() +        self.assertIsNone(models.Container.objects.get(pk=container_1.pk).parent) + +      def test_calculated_weight(self):          self.create_finds()          self.create_finds() | 
