summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2024-09-09 14:45:17 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2024-09-10 15:40:21 +0200
commit66232651ef2a2c1f331dc381a8f86f24a279ba85 (patch)
treee4c43e6209a35d84f3b1b362237570224f511fd5
parent39daa533e0b9d2a942223eeca817cdaa8887d69b (diff)
downloadIshtar-66232651ef2a2c1f331dc381a8f86f24a279ba85.tar.bz2
Ishtar-66232651ef2a2c1f331dc381a8f86f24a279ba85.zip
✨ find container history: manage first packaging info
-rw-r--r--archaeological_finds/migrations/0128_find_first_full_location.py33
-rw-r--r--archaeological_finds/models_finds.py74
-rw-r--r--archaeological_finds/templates/ishtar/sheet_find.html30
-rw-r--r--archaeological_finds/tests.py25
-rw-r--r--archaeological_warehouse/models.py16
-rw-r--r--archaeological_warehouse/tests.py21
6 files changed, 184 insertions, 15 deletions
diff --git a/archaeological_finds/migrations/0128_find_first_full_location.py b/archaeological_finds/migrations/0128_find_first_full_location.py
new file mode 100644
index 000000000..99e5b45f9
--- /dev/null
+++ b/archaeological_finds/migrations/0128_find_first_full_location.py
@@ -0,0 +1,33 @@
+# Generated by Django 2.2.24 on 2024-09-09 10:37
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_finds', '0127_find_treatments_container'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='find',
+ name='container_fisrt_full_location',
+ field=models.TextField(blank=True, default='', help_text='Updated as long as no packaging is attached', verbose_name='Container - first full location'),
+ ),
+ migrations.AddField(
+ model_name='find',
+ name='container_ref_fisrt_full_location',
+ field=models.TextField(blank=True, default='', help_text='Updated as long as no packaging is attached', verbose_name='Reference container - first full location'),
+ ),
+ migrations.AddField(
+ model_name='historicalfind',
+ name='container_fisrt_full_location',
+ field=models.TextField(blank=True, default='', help_text='Updated as long as no packaging is attached', verbose_name='Container - first full location'),
+ ),
+ migrations.AddField(
+ model_name='historicalfind',
+ name='container_ref_fisrt_full_location',
+ field=models.TextField(blank=True, default='', help_text='Updated as long as no packaging is attached', verbose_name='Reference container - first full location'),
+ ),
+ ]
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 55219d452..f8a978b67 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -2050,6 +2050,10 @@ class Find(
related_name="finds",
on_delete=models.SET_NULL,
)
+ container_fisrt_full_location = models.TextField(
+ _("Container - first full location"), default="", blank=True,
+ help_text=_("Updated as long as no packaging is attached")
+ )
container_ref = models.ForeignKey(
"archaeological_warehouse.Container",
verbose_name=_("Reference container"),
@@ -2058,6 +2062,10 @@ class Find(
related_name="finds_ref",
on_delete=models.SET_NULL,
)
+ container_ref_fisrt_full_location = models.TextField(
+ _("Reference container - first full location"), default="", blank=True,
+ help_text=_("Updated as long as no packaging is attached")
+ )
is_complete = models.NullBooleanField(_("Is complete?"), blank=True, null=True)
object_types = models.ManyToManyField(
ObjectType, verbose_name=_("Object types"), related_name="find", blank=True
@@ -2389,6 +2397,14 @@ class Find(
def show_url(self):
return reverse("show-find", args=[self.pk, ""])
+ @property
+ def has_packaging_for_current_container(self):
+ return FindTreatment.objects.filter(find=self, location_type__in=["B", "C"])
+
+ @property
+ def has_packaging_for_reference_container(self):
+ return FindTreatment.objects.filter(find=self, location_type__in=["B", "R"])
+
def public_representation(self):
dct = super(Find, self).public_representation()
dct.update(
@@ -3341,6 +3357,53 @@ class Find(
set_static_localisation_9.post_save = True
+ def update_current_full_location(self, full_location=None):
+ """
+ If relevant update full location of current container
+ :param full_location: provided if update is triggered from container
+ """
+ if getattr(self, "_container_fisrt_full_location", False) \
+ or self.has_packaging_for_current_container:
+ return False
+ self._container_fisrt_full_location = True
+ if self.container:
+ if not full_location:
+ full_location = self.container.generate_full_location()
+ if full_location == self.container_fisrt_full_location:
+ return False
+ self.container_fisrt_full_location = full_location
+ else:
+ if self.container_fisrt_full_location == "":
+ return False
+ self.container_fisrt_full_location = ""
+ return True
+
+ def update_ref_full_location(self, full_location=None):
+ """
+ If relevant update full location of reference container
+ :param full_location: provided if update is triggered from container
+ """
+ if getattr(self, "_container_ref_fisrt_full_location", False) \
+ or self.has_packaging_for_reference_container:
+ return False
+ self._container_ref_fisrt_full_location = True
+ if self.container_ref:
+ if not full_location:
+ full_location = self.container_ref.generate_full_location()
+ if full_location == self.container_ref_fisrt_full_location:
+ return False
+ self.container_ref_fisrt_full_location = full_location
+ else:
+ if self.container_ref_fisrt_full_location == "":
+ return False
+ self.container_ref_fisrt_full_location = ""
+ return True
+
+ def update_full_location(self):
+ updated = self.update_current_full_location()
+ updated |= self.update_ref_full_location()
+ return updated
+
def generate_index(self):
"""
Generate index based on operation or context record (based on
@@ -3402,6 +3465,10 @@ class Find(
except Container.DoesNotExist:
pass
+ if self.update_full_location():
+ self.save()
+ return True
+
updated = self.update_external_id(save=False)
if updated:
self._cached_label_checked = False
@@ -3557,9 +3624,11 @@ for attr in Find.HISTORICAL_M2M:
LOCATION_TYPE = [
["C", _("Current")],
["R", _("Reference")],
- ["B", _("Both")],
+ ["B", _("Reference/current")],
]
+LOCATION_TYPE_DICT = dict(LOCATION_TYPE)
+
class FindTreatment(models.Model):
"""
@@ -3584,6 +3653,9 @@ class FindTreatment(models.Model):
verbose_name_plural = _("Find - Treatments")
db_table = 'archaeological_finds_find_treatments'
+ def location_type_label(self):
+ return LOCATION_TYPE_DICT[self.location_type]
+
def generate_full_location(self):
if getattr(self, "_full_location_set", False) or self.full_location or (
not self.treatment.is_current_container_changer and
diff --git a/archaeological_finds/templates/ishtar/sheet_find.html b/archaeological_finds/templates/ishtar/sheet_find.html
index 465e2e1d5..371888317 100644
--- a/archaeological_finds/templates/ishtar/sheet_find.html
+++ b/archaeological_finds/templates/ishtar/sheet_find.html
@@ -360,7 +360,7 @@
<dl class="col-12 flex-wrap">
<dt>{% trans "Index" %}</dt>
<dd>
- {{ item.container.location }} - {{ item.container.index }}
+ {{ item.container.location }} - {{ item.container.index|unlocalize }}
</dd>
</dl>
</div>
@@ -387,8 +387,7 @@
<th>{% trans "Related finds (max. 15 displayed)" %}</th>
<th>{% trans "Doer" %}</th>
{% if can_view_container %}<th>{% trans "Container" %}</th>{% endif %}
- <th>{% trans "Start date" %}</th>
- <th>{% trans "End date" %}</th>
+ <th>{% trans "Date start/end" %}</th>
</tr>
{# {% for treatment in item.treatments.all %} #}
{% for items, treatment in item.non_modif_treatments %}
@@ -404,11 +403,22 @@
<td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
<td class='item-list'>{% for it in items %}<span>{{it}} {{it|link_to_window:request}}</span>{% endfor %}</td>
<td class='string'>{{ treatment.person|default_if_none:"-" }}</td>
- {% if can_view_container %}<td class='string'>{% for find_treatment in treatment.get_find_treatment_list %}{% if find_treatment.find.pk == item.pk %}{{ find_treatment.full_location|default_if_none:"-" }}{% endif %}{% endfor %}</td>{% endif %}
- <td class='string'>{{ treatment.start_date|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.end_date|default_if_none:"-" }}</td>
+ {% if can_view_container %}<td class='string'>{% for find_treatment in treatment.get_find_treatment_list %}{% if find_treatment.find.pk == item.pk %}{{ find_treatment.full_location|default_if_none:"-" }} <span class="badge badge-secondary">{{find_treatment.location_type_label}}</span>{% endif %}{% endfor %}</td>{% endif %}
+ <td class='string'>{{ treatment.start_date|default_if_none:"-" }}{% if treatment.end_date %}/{{ treatment.end_date|default_if_none:"-" }}{% endif %}</td>
</tr>
{% endfor %}
+ {% if can_view_container and item.container_fisrt_full_location %}
+ <tr>
+ <td class="string" colspan="6">{% trans "First packaging" %}</td>
+ <td class="string" colspan="2">{{ item.container_fisrt_full_location }} <span class="badge badge-secondary">{% if item.container_fisrt_full_location == item.container_ref_fisrt_full_location %}{% trans "Reference/current" %}{% else %}{% trans "Current" %}{% endif %}</span></td>
+ </tr>
+ {% endif %}
+ {% if can_view_container and item.container_ref_fisrt_full_location and item.container_ref_fisrt_full_location != item.container_fisrt_full_location %}
+ <tr>
+ <td class="string" colspan="6">{% trans "First packaging" %}</td>
+ <td class="string" colspan="2">{{ item.container_ref_fisrt_full_location }} <span class="badge badge-secondary">{% trans "Reference" %}</span></td>
+ </tr>
+ {% endif %}
</table>
{% endif %}
@@ -423,7 +433,7 @@
<th>{% trans "State" %}</th>
<th>{% trans "Related finds (max. 15 displayed)" %}</th>
<th>{% trans "Doer" %}</th>
- <th>{% trans "Container" %}</th>
+ {% if can_view_container %}<th>{% trans "Container" %}</th>{% endif %}
<th>{% trans "Start date" %}</th>
<th>{% trans "End date" %}</th>
</tr>
@@ -441,7 +451,7 @@
<td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
<td class='item-list'>{% for it in items %}<span>{{it}} {{it|link_to_window:request}}</span>{% endfor %}</td>
<td class='string'>{{ treatment.person|default_if_none:"-" }}</td>
- <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
+ {% if can_view_container %}<td class='string'>{{ treatment.container|default_if_none:"-" }}</td>{% endif %}
<td class='string'>{{ treatment.start_date|default_if_none:"-" }}</td>
<td class='string'>{{ treatment.end_date|default_if_none:"-" }}</td>
</tr>
@@ -461,7 +471,7 @@
<th>{% trans "State" %}</th>
<th>{% trans "Related finds (max. 15 displayed)" %}</th>
<th>{% trans "Doer" %}</th>
- <th>{% trans "Container" %}</th>
+ {% if can_view_container %}<th>{% trans "Container" %}</th>{% endif %}
<th>{% trans "Start date" %}</th>
<th>{% trans "End date" %}</th>
</tr>
@@ -479,7 +489,7 @@
<td class='string'>{{ treatment.treatment_state|default_if_none:"-" }}</td>
<td class='item-list'>{% for it in items %}<span>{{it}} {{ it|link_to_window:request}}</span>{% endfor %}</td>
<td class='string'>{{ treatment.person|default_if_none:"" }}</td>
- <td class='string'>{{ treatment.container|default_if_none:"-" }}</td>
+ {% if can_view_container %}<td class='string'>{{ treatment.container|default_if_none:"-" }}</td>{% endif %}
<td class='string'>{{ treatment.start_date|default_if_none:"" }}</td>
<td class='string'>{{ treatment.end_date|default_if_none:"" }}</td>
</tr>
diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py
index 3c38583ae..5a7e53849 100644
--- a/archaeological_finds/tests.py
+++ b/archaeological_finds/tests.py
@@ -2202,6 +2202,12 @@ class FindQATest(FindInit, TestCase):
location=main_warehouse,
container_type=ContainerType.objects.all()[0],
)
+ container2_base = Container.objects.create(
+ reference="Test2 base",
+ responsible=main_warehouse,
+ location=main_warehouse,
+ container_type=ContainerType.objects.all()[0],
+ )
packaging = models.TreatmentType.objects.get(txt_idx="packaging")
packaging.change_reference_location = True
packaging.change_current_location = False
@@ -2285,7 +2291,7 @@ class FindQATest(FindInit, TestCase):
find_0.container, find_0.container_ref = None, None
find_0.skip_history_when_saving = True
find_0.save()
- find_1.container, find_1.container_ref = None, None
+ find_1.container, find_1.container_ref = container2_base, container2_base
find_1.skip_history_when_saving = True
find_1.save()
@@ -2294,10 +2300,23 @@ class FindQATest(FindInit, TestCase):
response = c.post(reverse("find-qa-packaging", args=[pks]), data)
self.assertRedirects(response, "/success/")
for k in check:
+ 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":
+ value = None
+ # ref set for find_1 -> keep it
+ value2 = Container.objects.get(reference="Test2 base")
find = models.Find.objects.get(pk=find_0.pk)
- self.assertEqual(getattr(find, k), check[k])
+ self.assertEqual(getattr(find, k), value,
+ f"find-qa-packaging: find_0 {k} not set for data {data}")
find = models.Find.objects.get(pk=find_1.pk)
- self.assertEqual(getattr(find, k), check[k])
+ self.assertEqual(getattr(find, k), value2,
+ f"find-qa-packaging: find_1 {k} not set for data {data}")
final_nb_treat = models.Treatment.objects.count()
self.assertEqual(init_nb_treat + nb_treat, final_nb_treat)
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index d501eab1f..8bcc2bd65 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -1946,6 +1946,21 @@ class Container(
]
return actions
+ def update_find_location(self):
+ full_location = self.generate_full_location()
+ if not full_location:
+ return
+ for find in self.finds.all():
+ updated = find.update_current_full_location(full_location)
+ if updated:
+ find.skip_history_when_saving = True
+ find.save()
+ for find in self.finds_ref.all():
+ updated = find.update_ref_full_location(full_location)
+ if updated:
+ find.skip_history_when_saving = True
+ find.save()
+
def pre_save(self):
if self.parent == self:
self.parent = None
@@ -1992,6 +2007,7 @@ class Container(
logger.debug(f"[ishtar] archaeological_warehouse.models.Container.save - {self.pk} - {self.cached_label}")
self.pre_save()
super().save(*args, **kwargs)
+ self.update_find_location()
self._change_child_location(self)
updated = False
updated += self._prevent_parent_infinite_loop()
diff --git a/archaeological_warehouse/tests.py b/archaeological_warehouse/tests.py
index ebea75217..a5610893a 100644
--- a/archaeological_warehouse/tests.py
+++ b/archaeological_warehouse/tests.py
@@ -639,6 +639,8 @@ class ContainerTest(FindInit, TestCase):
self.assertEqual(models.Container.objects.count(), self.container_number + 1)
def test_change_location(self):
+ find = self.create_finds()[0][0]
+ find = Find.objects.get(pk=find.pk)
container = models.Container.objects.create(
reference="Test",
responsible=self.main_warehouse,
@@ -646,7 +648,6 @@ class ContainerTest(FindInit, TestCase):
container_type=models.ContainerType.objects.all()[0],
)
container.save()
- container = models.Container.objects.get(pk=container.pk)
container_2 = models.Container.objects.create(
reference="Test2",
responsible=self.main_warehouse,
@@ -654,8 +655,16 @@ class ContainerTest(FindInit, TestCase):
container_type=models.ContainerType.objects.all()[0],
parent=container,
)
+ container = models.Container.objects.get(pk=container.pk)
self.assertIn(self.main_warehouse.name, container.cached_location)
+ find.container = container
+ find.container_ref = container_2
+ find.save()
+ find = Find.objects.get(pk=find.pk)
+ self.assertEqual(find.container_fisrt_full_location, container.generate_full_location())
+ self.assertEqual(find.container_ref_fisrt_full_location, container_2.generate_full_location())
+
models.ContainerLocalisation.objects.create(
container=container,
division=self.div_link,
@@ -679,6 +688,16 @@ class ContainerTest(FindInit, TestCase):
)
container_2 = models.Container.objects.get(pk=container_2.pk)
self.assertEqual(container_2.location, other_warehouse)
+ find = Find.objects.get(pk=find.pk)
+ self.assertEqual(find.container_fisrt_full_location, container.generate_full_location())
+ self.assertEqual(find.container_ref_fisrt_full_location, container_2.generate_full_location())
+
+ find.container = None
+ find.container_ref = None
+ find.save()
+ find = Find.objects.get(pk=find.pk)
+ self.assertEqual(find.container_fisrt_full_location, "")
+ self.assertEqual(find.container_ref_fisrt_full_location, "")
"""
def test_reassign_existing_division_on_warehouse_change(self):