diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-10-22 15:51:43 +0200 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-10-24 10:45:09 +0200 |
| commit | 5d1b3d348c97a128e4eeaae270b4a70cc1998f8b (patch) | |
| tree | f2ca3db8f33ec0088add1918d22174fd7eb63ea9 | |
| parent | d52330d3f042bcd0aa2ad3c10288365922405d01 (diff) | |
| download | Ishtar-5d1b3d348c97a128e4eeaae270b4a70cc1998f8b.tar.bz2 Ishtar-5d1b3d348c97a128e4eeaae270b4a70cc1998f8b.zip | |
🐛 fix regenerate cached label of childs on container move (refs #6480)
| -rw-r--r-- | archaeological_finds/models_finds.py | 12 | ||||
| -rw-r--r-- | archaeological_warehouse/models.py | 41 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 43 |
3 files changed, 94 insertions, 2 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 40381a6bb..ec50c6f06 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -3397,7 +3397,7 @@ class Find( set_static_localisation_9.post_save = True - def update_current_full_location(self, full_location=None): + def update_current_full_location(self, full_location=None, return_value=False): """ If relevant update full location of current container :param full_location: provided if update is triggered from container @@ -3411,14 +3411,18 @@ class Find( full_location = self.container.generate_full_location() if full_location == self.container_fisrt_full_location: return False + if return_value: + return full_location self.container_fisrt_full_location = full_location else: if self.container_fisrt_full_location == "": return False + if return_value: + return "" self.container_fisrt_full_location = "" return True - def update_ref_full_location(self, full_location=None): + def update_ref_full_location(self, full_location=None, return_value=False): """ If relevant update full location of reference container :param full_location: provided if update is triggered from container @@ -3432,10 +3436,14 @@ class Find( full_location = self.container_ref.generate_full_location() if full_location == self.container_ref_fisrt_full_location: return False + if return_value: + return full_location self.container_ref_fisrt_full_location = full_location else: if self.container_ref_fisrt_full_location == "": return False + if return_value: + return "" self.container_ref_fisrt_full_location = "" return True diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 8c9a94f06..be6c69eec 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -2027,9 +2027,46 @@ class Container( q.update(cached_division="") return ((self.__class__, q.values_list("id", flat=True)),) + def _update_childs_divisions(self): + Find = apps.get_model("archaeological_finds", "Find") + q = Container.objects.filter(parent_id=self.id) + for child in q.all(): + self.update_weight() + cached_division = child._generate_cached_division() + cached_label = child._generate_cached_label() + cached_weight = child._generate_cached_weight() + Container.objects.filter(pk=child.pk).update( + cached_division=cached_division, + cached_label=cached_label, + cached_weight=cached_weight + ) + + # update location of associated find + full_location = Container.objects.get(pk=child.pk).generate_full_location() + for find in child.finds_ref.all(): + value = find.update_ref_full_location(full_location, return_value=True) + if value is not False: + Find.objects.filter(pk=find.pk).update( + container_ref_fisrt_full_location=value + ) + for find in child.finds.all(): + value = find.update_current_full_location(full_location, return_value=True) + if value is not False: + Find.objects.filter(pk=find.pk).update( + container_fisrt_full_location=value + ) + + # TODO update last treatment? + # warning - if a new treatment is created via move container + # it will be created after this is triggered... not easy to manage... + + child._update_childs_divisions() + def save(self, *args, **kwargs): + self._cached_location, self._cached_parent = None, None if self.pk: logger.debug(f"[ishtar] archaeological_warehouse.models.Container.save - {self.pk} - {self.cached_label}") + self._cached_location, self._cached_parent = Container.objects.filter(pk=self.pk).values_list("location_id", "parent_id").all()[0] self.pre_save() super().save(*args, **kwargs) self.update_find_location() @@ -2040,6 +2077,10 @@ class Container( updated += self._calculate_weight() + # update cached_label for childs + if self._cached_location != self.location_id or self._cached_parent != self.parent_id: + self._update_childs_divisions() + if not self.index and not self.container_type.stationary: self.skip_history_when_saving = True q = ( diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index 371d0d782..20e0e20f0 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -861,10 +861,33 @@ class ContainerTest(FindInit, TestCase): def test_change_location(self): find = self.create_finds()[0][0] find = Find.objects.get(pk=find.pk) + + main_container_1 = models.Container.objects.create( + reference="Test - main container", + responsible=self.main_warehouse, + location=self.main_warehouse, + container_type=models.ContainerType.objects.all()[1], + ) + main_container_2 = models.Container.objects.create( + reference="Test - main container 2", + responsible=self.main_warehouse, + location=self.main_warehouse, + container_type=models.ContainerType.objects.all()[1], + ) + top_container_1 = models.Container.objects.create( + reference="Test - top container", + responsible=self.main_warehouse, + location=self.main_warehouse, + container_type=models.ContainerType.objects.all()[1], + parent=main_container_1 + ) + + # simple localisation container = models.Container.objects.create( reference="Test", responsible=self.main_warehouse, location=self.main_warehouse, + parent=top_container_1, container_type=models.ContainerType.objects.all()[0], ) container.save() @@ -895,6 +918,26 @@ class ContainerTest(FindInit, TestCase): division__warehouse=self.main_warehouse ).count() ) + + # test cascade update + top_container_1.parent = main_container_2 + top_container_1.save() + container = models.Container.objects.get(pk=container.pk) + container_2 = models.Container.objects.get(pk=container_2.pk) + find = Find.objects.get(pk=find.pk) + self.assertTrue( + find.container_fisrt_full_location.startswith( + main_container_2.generate_full_location() + ) + ) + self.assertTrue( + find.container_ref_fisrt_full_location.startswith( + main_container_2.generate_full_location() + ) + ) + self.assertEqual(find.container_fisrt_full_location, container.generate_full_location()) + self.assertEqual(find.container_ref_fisrt_full_location, container_2.generate_full_location()) + # changing location remove irrelevant localisation other_warehouse = models.Warehouse.objects.create( name="Other", warehouse_type=models.WarehouseType.objects.all()[0] |
