diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-12-12 08:30:22 +0100 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2025-12-12 17:24:41 +0100 |
| commit | 0b796e98bf8c196b3ec5005720925178782c046d (patch) | |
| tree | b98b84f9cc2db3b8d782a4c974878640235051d9 | |
| parent | d317f541575a7ef59e7b06df5edc5b9c1560512f (diff) | |
| download | Ishtar-0b796e98bf8c196b3ec5005720925178782c046d.tar.bz2 Ishtar-0b796e98bf8c196b3ec5005720925178782c046d.zip | |
🐛 treatment container history: fix history on container move (refs #6532)
| -rw-r--r-- | archaeological_finds/models_finds.py | 22 | ||||
| -rw-r--r-- | archaeological_finds/models_treatments.py | 17 | ||||
| -rw-r--r-- | archaeological_finds/tests.py | 2 | ||||
| -rw-r--r-- | archaeological_warehouse/forms.py | 55 | ||||
| -rw-r--r-- | archaeological_warehouse/tests.py | 70 | ||||
| -rw-r--r-- | ishtar_common/management/commands/migrate_find_container_v4_2.py | 4 |
6 files changed, 142 insertions, 28 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 42725f881..1a08eb171 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -2582,7 +2582,7 @@ class Find( @property def has_packaging_for_current_container(self): - return FindTreatment.objects.filter(find=self, location_type__in=["B", "C"]) + return FindTreatment.objects.filter(find=self, location_type__in=["B", "C"]).exists() @staticmethod def _get_upstream_count(upstream_id, idx): @@ -2611,7 +2611,7 @@ class Find( @property def has_packaging_for_reference_container(self): - return FindTreatment.objects.filter(find=self, location_type__in=["B", "R"]) + return FindTreatment.objects.filter(find=self, location_type__in=["B", "R"]).exists() def public_representation(self): dct = super(Find, self).public_representation() @@ -3607,8 +3607,10 @@ class Find( :param full_location: provided if update is triggered from container """ if getattr(self, "_container_fisrt_full_location", False) \ + or not self.pk \ or self.has_packaging_for_current_container: return False + self._container_fisrt_full_location = True if self.container: if not full_location: @@ -3624,6 +3626,9 @@ class Find( if return_value: return "" self.container_fisrt_full_location = "" + Find.objects.filter(pk=self.pk).update( + container_fisrt_full_location=self.container_fisrt_full_location + ) return True def update_ref_full_location(self, full_location=None, return_value=False): @@ -3632,8 +3637,11 @@ class Find( :param full_location: provided if update is triggered from container """ if getattr(self, "_container_ref_fisrt_full_location", False) \ + or not self.pk \ + or self.has_packaging_for_current_container \ or self.has_packaging_for_reference_container: return False + # if current container has already changed - do not change first self._container_ref_fisrt_full_location = True if self.container_ref: if not full_location: @@ -3649,6 +3657,9 @@ class Find( if return_value: return "" self.container_ref_fisrt_full_location = "" + Find.objects.filter(pk=self.pk).update( + container_ref_fisrt_full_location=self.container_ref_fisrt_full_location + ) return True def update_full_location(self): @@ -3717,9 +3728,7 @@ class Find( except Container.DoesNotExist: pass - if self.update_full_location(): - self.save() - return True + self.update_full_location() updated = self.update_external_id(save=False) if updated: @@ -3901,7 +3910,8 @@ class FindTreatment(Imported): on_delete=models.CASCADE ) full_location = models.TextField(_("Full location"), default="", blank=True) - location_type = models.CharField(_("Location type"), max_length=1, choices=LOCATION_TYPE, + location_type = models.CharField(_("Location type"), max_length=1, + choices=LOCATION_TYPE, default="C") class Meta: diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index faf448b63..60ae4a45a 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -983,6 +983,23 @@ class Treatment( post_save.connect(cached_label_changed, sender=Treatment) +def treatment_attached_changed(sender, **kwargs): + # force full location + instance = kwargs.get("instance", None) + find_pk_set = kwargs.get("pk_set", None) + if not find_pk_set or not instance: + return + for find_id in find_pk_set: + q = FindTreatment.objects.filter(find_id=find_id, treatment_id=instance.pk) + if not q.count(): + continue + for ft in q.all(): + ft.generate_full_location() + + +m2m_changed.connect(treatment_attached_changed, sender=Treatment.finds.through) + + def pre_delete_treatment(sender, **kwargs): treatment = kwargs.get("instance") for find in Find.objects.filter(upstream_treatment=treatment).all(): diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index babaf4380..b51a32900 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -2556,8 +2556,6 @@ class FindQATest(FindInit, TestCase): value = check[k] value2 = check[k] if k == "container" and data["qa-packaging-container_to_change"] == "reference": - # if current not set -> auto set container to container_ref - value = check["container_ref"] # current set for find_1 -> keep it value2 = Container.objects.get(reference="Test2 base") if k == "container_ref" and data["qa-packaging-container_to_change"] == "current": diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py index 5b22362c4..8e272e9c2 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -46,6 +46,7 @@ from archaeological_finds.models import ( ConservatoryState, Find, FindBasket, + FindTreatment, IntegrityType, MaterialType, ObjectType, @@ -859,21 +860,33 @@ class QAContainerMoveForm(QABasePackagingForm): def save(self, items, user): location_id = self.cleaned_data.get("qalocation", None) parent_id = self.cleaned_data.get("qaparent", None) + + changed = [] for container in self.items: - changed = False + # move the container if parent_id and parent_id != container.parent_id: container.parent_id = parent_id - changed = True + models.Container.objects.filter(id=container.id).update( + parent_id=parent_id + ) + changed.append(container) if location_id and location_id != container.location_id: container.location_id = location_id - # remove parent if do not share the same location - if not changed and container.parent \ - and container.parent.location != container.location: - container.parent = None - changed = True - if changed: - container.save() + models.Container.objects.filter(id=container.id).update( + location_id=location_id + ) + if container not in changed: + # remove parent if do not share the same location + if container.parent \ + and container.parent.location != container.location: + container.parent = None + models.Container.objects.filter(id=container.id).update( + parent=None + ) + changed.append(container) if not self.cleaned_data.get("create_treatment", False): + for container in changed: + container.save() return treat_type = TreatmentType.objects.get(pk=self.cleaned_data['treatment_type']) treat_input_status = TreatmentInputStatus.get_validated_state() @@ -902,8 +915,30 @@ class QAContainerMoveForm(QABasePackagingForm): q = Find.objects.filter(Q(container=container) | Q(container_ref=container)) if not q.count(): continue + loca = container.generate_full_location() for find in q.all(): - t.finds.add(find) + if find.update_current_full_location(): + Find.objects.filter(pk=find.id).update( + container_fisrt_full_location=find.container_fisrt_full_location + ) + if find.update_ref_full_location(): + Find.objects.filter(pk=find.id).update( + container_ref_fisrt_full_location=find.container_ref_fisrt_full_location + ) + location_type = "C" + if find.container_ref == container: + if find.container == container: + location_type = "B" + else: + location_type = "R" + FindTreatment.objects.create( + find=find, treatment=t, + location_type=location_type, + full_location=loca + ) t.save() # force find container history + for container in changed: # container post treatment after save + container.save() + diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py index 382efb769..bc31d0ba6 100644 --- a/archaeological_warehouse/tests.py +++ b/archaeological_warehouse/tests.py @@ -631,9 +631,12 @@ class ContainerQATest(FindInit, TestCase): def test_move(self): c = Client() - find_0 = self.finds[0] + find_0 = Find.objects.get(pk=self.finds[0].pk) find_0.container = self.container_3 + find_0.container_ref = self.container_3 find_0.save() + find = Find.objects.get(pk=find_0.pk) + self.assertTrue(find.container_fisrt_full_location) pks_1 = f"{self.container_3.pk}-{self.container_4.pk}" pks_2 = str(self.container_1.pk) @@ -656,18 +659,33 @@ class ContainerQATest(FindInit, TestCase): packaging = TreatmentType.objects.get(txt_idx="packaging") - def check_location_of_children(): + def check_location_of_children(idx): # check change location of children container3 = models.Container.objects.get(pk=self.container_3.pk) self.assertEqual(container3.location, self.alt_warehouse) container4 = models.Container.objects.get(pk=self.container_4.pk) self.assertEqual(container4.location, self.alt_warehouse) - def check_reinit_parent(): + def check_reinit_parent(idx): # reinit parent when not provided and location changed container = models.Container.objects.get(pk=self.container_3.pk) self.assertEqual(container.parent, None) + def init_treatment(find_0): + # create a first packaging treatment + treat_status = TreatmentStatus.get_completed_state() + t = Treatment.objects.create( + container=self.container_3, + year=2024, + start_date=datetime.date(2024, 2, 29), + location=self.main_warehouse, + treatment_status=treat_status + ) + treat_type = TreatmentType.objects.get(txt_idx="packaging") + t.treatment_types.add(treat_type) + t.save() + t.finds.add(find_0) + t.save() # force find container history data_check_lst = [ ( @@ -677,6 +695,7 @@ class ContainerQATest(FindInit, TestCase): {"parent": self.container_2}, 0, pks_1, + None, None ), ( @@ -686,6 +705,7 @@ class ContainerQATest(FindInit, TestCase): {"location": self.alt_warehouse}, 0, pks_1, + None, None ), ( @@ -698,10 +718,24 @@ class ContainerQATest(FindInit, TestCase): {"parent": self.container_2}, 2, pks_1, + None, None ), ( { + "qa-move-qaparent": self.container_2.pk, + "qa-move-create_treatment": True, + "qa-move-year": 2019, + "qa-move-treatment_type": packaging.pk, + }, + {"parent": self.container_2}, + 2, + pks_1, + None, + init_treatment + ), + ( + { "qa-move-qalocation": self.alt_warehouse.pk, "qa-move-create_treatment": True, "qa-move-year": 2019, @@ -710,6 +744,7 @@ class ContainerQATest(FindInit, TestCase): {"location": self.alt_warehouse}, 2, pks_1, + None, None ), ( @@ -719,7 +754,8 @@ class ContainerQATest(FindInit, TestCase): {"location": self.alt_warehouse}, 0, pks_2, - check_location_of_children + check_location_of_children, + None ), ( { @@ -728,12 +764,13 @@ class ContainerQATest(FindInit, TestCase): {"location": self.alt_warehouse}, 0, pks_1, - check_reinit_parent + check_reinit_parent, + None ), ] for idx, lst in enumerate(data_check_lst): - data, check, nb_treat, pks, extra_check = lst + data, check, nb_treat, pks, extra_check, pre_init = lst # reinit self.container_1.location = self.main_warehouse self.container_1.parent = None @@ -744,6 +781,12 @@ class ContainerQATest(FindInit, TestCase): self.container_4.location = self.main_warehouse self.container_4.parent = self.container_1 self.container_4.save() + find_0.save() + FindTreatment.objects.exclude(id__isnull=True).delete() + Treatment.objects.exclude(id__isnull=True).delete() + + if pre_init: + pre_init(find_0) init_nb_treat = Treatment.objects.count() @@ -758,7 +801,7 @@ class ContainerQATest(FindInit, TestCase): self.assertEqual(init_nb_treat + nb_treat, final_nb_treat) if extra_check: - extra_check() + extra_check(idx) if not final_nb_treat: self.assertEqual(FindTreatment.objects.filter(find=find_0).count(), 0) @@ -774,6 +817,19 @@ class ContainerQATest(FindInit, TestCase): self.assertTrue(ft.full_location) self.assertTrue(ft.location_type) + find = Find.objects.get(pk=find_0.pk) + if pre_init: + # pre init add a packaging -> first full location is not changed + self.assertNotEqual( + find.container_fisrt_full_location, + find.container.generate_full_location() + ) + else: + self.assertEqual( + find.container_fisrt_full_location, + find.container.generate_full_location() + ) + class ContainerTest(FindInit, TestCase): fixtures = WAREHOUSE_FIXTURES diff --git a/ishtar_common/management/commands/migrate_find_container_v4_2.py b/ishtar_common/management/commands/migrate_find_container_v4_2.py index ac167bc6a..d40c74b61 100644 --- a/ishtar_common/management/commands/migrate_find_container_v4_2.py +++ b/ishtar_common/management/commands/migrate_find_container_v4_2.py @@ -34,7 +34,7 @@ def migrate(log=True): ) q = Find.objects.filter(Q(container__isnull=False) | Q(container_ref__isnull=False)).filter( - container_fisrt_full_location="" + Q(container_fisrt_full_location="") | Q(container_ref_fisrt_full_location="") ) total = q.count() ref_time = datetime.datetime.now() @@ -44,8 +44,6 @@ def migrate(log=True): write_output(base_lbl, idx, total, ref_time) if find.update_full_location(): changed.append(("Find", str(find), find.pk)) - find.no_post_process() - find.save() if not quiet: sys.stdout.write( |
