From 16a47f887447ecccd56fc848aee95fa56af92548 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 24 Feb 2021 19:14:37 +0100 Subject: get_values: get containers from operation - material_types_code from finds --- archaeological_finds/models_finds.py | 25 +++++++++++++++++++++++++ archaeological_finds/tests.py | 18 ++++++++++++++++++ archaeological_operations/models.py | 26 +++++++++++++++++++++++--- archaeological_operations/tests.py | 28 ++++++++++++++++++++++++++++ archaeological_warehouse/models.py | 5 +++-- ishtar_common/views.py | 3 ++- 6 files changed, 99 insertions(+), 6 deletions(-) diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 3924ee106..cf58952c9 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1845,12 +1845,37 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, ("base_finds.", _("List of associated base finds")), ] + def get_material_types_code(self) -> str: + """ + Return pipe separated material type code inside a container + """ + materials = set() + for material in self.material_types.exclude( + code__isnull=True).values_list("code", flat=True): + materials.add(material) + return "|".join(sorted(materials)) + + def get_material_types(self) -> str: + """ + Return comma separated string of material types inside a container + """ + materials = set() + for material in self.material_types.exclude( + label__isnull=True).values_list("label", flat=True): + materials.add(material) + return ", ".join(sorted(materials)) + def get_values(self, prefix='', no_values=False, filtr=None, **kwargs): no_base_finds = False if "no_base_finds" in kwargs: no_base_finds = kwargs["no_base_finds"] values = super(Find, self).get_values( prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) + if not filtr or prefix + 'material_types' in filtr: + values[prefix + 'material_types'] = self.get_material_types() + if not filtr or prefix + 'material_types_code' in filtr: + values[prefix + 'material_types_code'] = \ + self.get_material_types_code() if no_base_finds: return values # by default attach first basefind data diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index bede89b51..afcdc713e 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -1004,6 +1004,24 @@ class FindTest(FindInit, TestCase): self.assertEqual(models.BaseFind.objects.filter( pk=self.base_finds[0].pk).count(), 0) + def test_get_material_types(self): + mat0 = models.MaterialType.objects.all()[0] + mat1 = models.MaterialType.objects.all()[1] + self.create_finds() + find0 = self.finds[0] + self.assertEqual(find0.get_material_types(), "") + self.assertEqual(find0.get_material_types_code(), "") + + find0.material_types.add(mat0) + find0.material_types.add(mat1) + + self.assertEqual( + find0.get_material_types(), + ", ".join(sorted([mat0.label, mat1.label]))) + self.assertEqual( + find0.get_material_types_code(), + "|".join(sorted([mat0.code, mat1.code]))) + class FindSearchTest(FindInit, TestCase, SearchText): fixtures = WAREHOUSE_FIXTURES diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index b7841450c..240283d1a 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -22,6 +22,7 @@ import datetime from itertools import groupby import uuid +from django.apps import apps from django.conf import settings from django.contrib.gis.db import models from django.contrib.gis.db.models.aggregates import Union @@ -1234,6 +1235,22 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, def __str__(self): return self.cached_label or "" + DOC_VALUES = [ + ("context_records.", _("List of associated context records")), + ("containers.", _("List of associated containers")), + ] + + def get_containers_values(self, filtr, exclude) -> list: # Container value + # list + Container = apps.get_model("archaeological_warehouse", "Container") + containers = [] + q = Container.objects.filter( + finds__base_finds__context_record__operation=self).distinct("index") + exclude += ["operation", "context_record"] + for c in q.order_by("index").all(): + containers.append(c.get_values(filtr=filtr, exclude=exclude)) + return containers + def get_values(self, prefix='', no_values=False, filtr=None, **kwargs): values = super(Operation, self).get_values( prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) @@ -1241,14 +1258,17 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, exclude = kwargs.get("exclude", []) if prefix: return values - if (not filtr or prefix + 'context_records' in filtr) and \ - prefix + "context_records" not in exclude: + if (not filtr or 'context_records' in filtr) and \ + "context_records" not in exclude: kwargs["no_base_finds"] = False - values[prefix + 'context_records'] = [ + values['context_records'] = [ cr.get_values(prefix=prefix, no_values=True, filtr=None, **kwargs) for cr in self.context_record.all() ] + if (not filtr or "containers" in filtr) \ + and "context_records" not in exclude: + values["containers"] = self.get_containers_values(filtr, exclude) return values def public_representation(self): diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index d8c61c642..650a839aa 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -25,6 +25,7 @@ import tempfile import locale import zipfile +from django.apps import apps from django.conf import settings from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType @@ -1732,6 +1733,33 @@ class OperationTest(TestCase, OperationInitTest): doc2 = Document.objects.get(pk=doc2.pk) self.assertEqual(c_index + 2, doc2.index) + def test_get_containers(self): + Find = apps.get_model("archaeological_finds", "Find") + BaseFind = apps.get_model("archaeological_finds", "BaseFind") + Warehouse = apps.get_model("archaeological_warehouse", "Warehouse") + WarehouseType = apps.get_model("archaeological_warehouse", + "WarehouseType") + Container = apps.get_model("archaeological_warehouse", "Container") + ContainerType = apps.get_model("archaeological_warehouse", + "ContainerType") + operation = self.operations[0] + hc, __ = Unit.objects.get_or_create(txt_idx='not-in-context', order=10) + cr = ContextRecord.objects.create( + operation=operation, unit=hc) + bf = BaseFind.objects.create(context_record=cr) + f = Find.objects.create() + f.base_finds.add(bf) + wt = WarehouseType.objects.create(label='WT') + w = Warehouse.objects.create(name="Warehouse", warehouse_type=wt) + ct = ContainerType.objects.create(label='CT') + c = Container.objects.create(reference="Test", location=w, + container_type=ct) + f.container = c + f.save() + + values = operation.get_containers_values([], []) + self.assertEqual(len(values), 1) + class LockTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index d049b8093..16bbaab40 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -1438,7 +1438,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem, def get_material_types_code(self) -> str: """ - Return dash separated material type code inside a container + Return pipe separated material type code inside a container """ materials = set() for material in self.finds.exclude( @@ -1463,7 +1463,8 @@ class Container(DocumentItem, Merge, LightHistorizedItem, prefix=prefix, no_values=no_values, filtr=filtr, **kwargs) from_find = prefix.startswith("container_") or \ prefix.startswith("container_ref_") - if (not filtr or prefix + 'finds' in filtr) and not from_find: + if (not filtr or prefix + 'finds' in filtr) and not from_find and \ + "finds" not in kwargs.get("exclude", []): kwargs["exclude"] = [prefix + "container", prefix + "container_ref"] # prevent recursive call values[prefix + 'finds'] = [ diff --git a/ishtar_common/views.py b/ishtar_common/views.py index b9cf98a87..45a7530c7 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1217,10 +1217,11 @@ class GenerateLabelView(GenerateView): get_list = get_item( model, None, model.SLUG, own_table_cols=["id"])( request, no_link=True, no_limit=True) + item_list = json.loads(get_list.content.decode("utf-8"))["rows"] try: objects = [ model.objects.get(pk=int(dct["id"])) - for dct in json.loads(get_list.content.decode("utf-8"))["rows"] + for dct in item_list ] except model.DoesNotExist: raise Http404() -- cgit v1.2.3