summaryrefslogtreecommitdiff
path: root/archaeological_warehouse/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2021-03-19 11:23:36 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2021-03-19 11:23:36 +0100
commitfe8b8f657a4640bdc814651ef11aced916fdc9e3 (patch)
treecc628849cc6a15d19d68f8d0f0d953b1e2e833c0 /archaeological_warehouse/models.py
parentced270d071384046eb3b9a85572dc817c7ef042c (diff)
downloadIshtar-fe8b8f657a4640bdc814651ef11aced916fdc9e3.tar.bz2
Ishtar-fe8b8f657a4640bdc814651ef11aced916fdc9e3.zip
Format - black: warehouse
Diffstat (limited to 'archaeological_warehouse/models.py')
-rw-r--r--archaeological_warehouse/models.py1049
1 files changed, 591 insertions, 458 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index fc0184990..29615b6ef 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2012-2017 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
@@ -27,24 +27,38 @@ from django.contrib.postgres.indexes import GinIndex
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.db.models import Q, Max, Count
-from django.db.models.signals import post_save, post_delete, m2m_changed, \
- pre_delete
+from django.db.models.signals import post_save, post_delete, m2m_changed, pre_delete
from django.template.defaultfilters import slugify
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy
from django.apps import apps
-from ishtar_common.data_importer import post_importer_action, \
- pre_importer_action
+from ishtar_common.data_importer import post_importer_action, pre_importer_action
from ishtar_common.model_managers import ExternalIdManager, UUIDModelManager
from ishtar_common.models import ValueGetter, get_current_profile
-from ishtar_common.models_common import GeneralType, \
- LightHistorizedItem, OwnPerms, Address, post_save_cache, \
- DashboardFormItem, document_attached_changed, SearchAltName, \
- DynamicRequest, GeoItem, CompleteIdentifierItem, SearchVectorConfig, \
- DocumentItem, QuickAction, MainItem, Merge
+from ishtar_common.models_common import (
+ GeneralType,
+ LightHistorizedItem,
+ OwnPerms,
+ Address,
+ post_save_cache,
+ DashboardFormItem,
+ document_attached_changed,
+ SearchAltName,
+ DynamicRequest,
+ GeoItem,
+ CompleteIdentifierItem,
+ SearchVectorConfig,
+ DocumentItem,
+ QuickAction,
+ MainItem,
+ Merge,
+)
from ishtar_common.model_merging import merge_model_objects
-from ishtar_common.utils import cached_label_changed, \
- cached_label_and_geo_changed, get_generated_id
+from ishtar_common.utils import (
+ cached_label_changed,
+ cached_label_and_geo_changed,
+ get_generated_id,
+)
from ishtar_common.data_importer import ImporterError
@@ -81,7 +95,7 @@ class DivisionContainer(DashboardFormItem):
def number_divisions(self):
q = {
self.BASE_QUERY_LOCATION + "__id": self.pk,
- "container_type__stationary": True
+ "container_type__stationary": True,
}
return Container.objects.filter(**q).count()
@@ -89,7 +103,7 @@ class DivisionContainer(DashboardFormItem):
def number_containers(self):
q = {
self.BASE_QUERY_LOCATION + "__id": self.pk,
- "container_type__stationary": False
+ "container_type__stationary": False,
}
return Container.objects.filter(**q).count()
@@ -111,27 +125,30 @@ class DivisionContainer(DashboardFormItem):
@property
def number_of_containers(self):
- return Container.objects.filter(
- **{self.BASE_QUERY_LOCATION: self}).count()
+ return Container.objects.filter(**{self.BASE_QUERY_LOCATION: self}).count()
def _number_of_finds_by_place(self):
Find = apps.get_model("archaeological_finds", "Find")
return self._number_of_items_by_place(
- Find, division_key='inside_container__container__')
+ Find, division_key="inside_container__container__"
+ )
@property
def number_of_finds_by_place(self, update=False):
- return self._get_or_set_stats('_number_of_finds_by_place', update,
- expected_type=list)
+ return self._get_or_set_stats(
+ "_number_of_finds_by_place", update, expected_type=list
+ )
def _number_of_containers_by_place(self):
return self._number_of_items_by_place(
- ContainerTree, 'container_parent__', 'container__children')
+ ContainerTree, "container_parent__", "container__children"
+ )
@property
def number_of_containers_by_place(self, update=False):
- return self._get_or_set_stats('_number_of_containers_by_place', update,
- expected_type=list)
+ return self._get_or_set_stats(
+ "_number_of_containers_by_place", update, expected_type=list
+ )
def _get_divisions(self, current_path, remaining_division, depth=0):
if not remaining_division:
@@ -144,7 +161,7 @@ class DivisionContainer(DashboardFormItem):
base_q = Container.objects.filter(**{query_location: self})
q = base_q
- if self.BASE_QUERY_LOCATION == 'location':
+ if self.BASE_QUERY_LOCATION == "location":
exclude = "parent_"
for idx in range(depth):
exclude += "_parent_"
@@ -161,31 +178,28 @@ class DivisionContainer(DashboardFormItem):
if not q.count():
return [current_path]
q = q.values(
- 'id', 'reference', 'container_type__label', 'container_type_id'
- ).order_by('container_type__label', 'reference')
+ "id", "reference", "container_type__label", "container_type_id"
+ ).order_by("container_type__label", "reference")
for ref in q.all():
- if ref['reference'] == old_ref and \
- ref["container_type__label"] == ct:
+ if ref["reference"] == old_ref and ref["container_type__label"] == ct:
continue
- old_ref = ref['reference']
+ old_ref = ref["reference"]
ct = ref["container_type__label"]
cpath = current_path[:]
lbl = self.DIVISION_TEMPLATE.format(
- id=ref["id"], container=ref["container_type__label"],
- ref=ref['reference'])
+ id=ref["id"],
+ container=ref["container_type__label"],
+ ref=ref["reference"],
+ )
cpath.append((ref["id"], lbl))
query = {
- "containers__parent__reference": ref['reference'],
- "containers__parent__container_type_id": ref[
- "container_type_id"],
- "containers__" + self.BASE_QUERY_LOCATION: self
+ "containers__parent__reference": ref["reference"],
+ "containers__parent__container_type_id": ref["container_type_id"],
+ "containers__" + self.BASE_QUERY_LOCATION: self,
}
- remaining_division = list(
- ContainerType.objects.filter(
- **query).distinct())
- for r in self._get_divisions(cpath, remaining_division[:],
- depth + 1):
+ remaining_division = list(ContainerType.objects.filter(**query).distinct())
+ for r in self._get_divisions(cpath, remaining_division[:], depth + 1):
res.append(r)
return res
@@ -195,13 +209,10 @@ class DivisionContainer(DashboardFormItem):
:return: ordered list of available paths. Each path is a list of
tuple with the container type and the full reference.
"""
- q = {
- "containers__" + self.BASE_QUERY_LOCATION: self
- }
- if self.BASE_QUERY_LOCATION == 'location':
+ q = {"containers__" + self.BASE_QUERY_LOCATION: self}
+ if self.BASE_QUERY_LOCATION == "location":
q["containers__parent"] = None
- top_divisions = list(
- ContainerType.objects.filter(**q).distinct())
+ top_divisions = list(ContainerType.objects.filter(**q).distinct())
divisions = self._get_divisions([], top_divisions)
return divisions
@@ -218,9 +229,7 @@ class DivisionContainer(DashboardFormItem):
for idx, p in enumerate(reversed(cpath)):
container_id, __ = p
div_key = division_key + "parent__" * idx
- attrs = {
- div_key + "id": container_id
- }
+ attrs = {div_key + "id": container_id}
q = q.filter(**attrs)
if count_filter:
q = q.filter(**{count_filter: None})
@@ -236,10 +245,10 @@ class DivisionContainer(DashboardFormItem):
final_res.append(current_res[:])
current_res = []
depth = len(path)
- if path[-1] == '-':
+ if path[-1] == "-":
continue
path = [k[1] for k in path]
- path = path + ['' for __ in range(len_divisions - len(path))]
+ path = path + ["" for __ in range(len_divisions - len(path))]
current_res.append((path, nb))
final_res.append(current_res[:])
return final_res
@@ -249,25 +258,32 @@ class WarehouseType(GeneralType):
class Meta:
verbose_name = _("Warehouse type")
verbose_name_plural = _("Warehouse types")
- ordering = ('label',)
+ ordering = ("label",)
post_save.connect(post_save_cache, sender=WarehouseType)
post_delete.connect(post_save_cache, sender=WarehouseType)
-NO_DIVISION_ERROR = _(
- "The division number {} has not been set for the warehouse {}.")
+NO_DIVISION_ERROR = _("The division number {} has not been set for the warehouse {}.")
-class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
- OwnPerms, MainItem, DivisionContainer, ValueGetter):
- SLUG = 'warehouse'
+class Warehouse(
+ Address,
+ DocumentItem,
+ GeoItem,
+ CompleteIdentifierItem,
+ OwnPerms,
+ MainItem,
+ DivisionContainer,
+ ValueGetter,
+):
+ SLUG = "warehouse"
APP = "archaeological-warehouse"
MODEL = "warehouse"
- SHOW_URL = 'show-warehouse'
- DELETE_URL = 'delete-warehouse'
- TABLE_COLS = ['name', 'warehouse_type__label']
+ SHOW_URL = "show-warehouse"
+ DELETE_URL = "delete-warehouse"
+ TABLE_COLS = ["name", "warehouse_type__label"]
NEW_QUERY_ENGINE = True
BASE_SEARCH_VECTORS = [
SearchVectorConfig("name"),
@@ -278,7 +294,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
SearchVectorConfig("comment", "local"),
]
COL_LABELS = {
- 'warehouse_type__label': _("Type"),
+ "warehouse_type__label": _("Type"),
}
EXTRA_REQUEST_KEYS = {
@@ -288,28 +304,28 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
}
# alternative names of fields for searches
ALT_NAMES = {
- 'name': SearchAltName(
- pgettext_lazy("key for text search", "name"),
- 'name__iexact'
+ "name": SearchAltName(
+ pgettext_lazy("key for text search", "name"), "name__iexact"
),
- 'warehouse_type': SearchAltName(
+ "warehouse_type": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'warehouse_type__label__iexact'
+ "warehouse_type__label__iexact",
+ ),
+ "town": SearchAltName(
+ pgettext_lazy("key for text search", "town"),
+ "precise_town__cached_label__iexact",
),
- 'town':
- SearchAltName(
- pgettext_lazy("key for text search", "town"),
- 'precise_town__cached_label__iexact'
- ),
}
GEO_LABEL = "name"
DOWN_MODEL_UPDATE = ["containers"]
CACHED_LABELS = []
QA_LOCK = QuickAction(
- url="warehouse-qa-lock", icon_class="fa fa-lock",
- text=_("Lock/Unlock"), target="many",
- rights=['change_warehouse', 'change_own_warehouse']
+ url="warehouse-qa-lock",
+ icon_class="fa fa-lock",
+ text=_("Lock/Unlock"),
+ target="many",
+ rights=["change_warehouse", "change_own_warehouse"],
)
QUICK_ACTIONS = [QA_LOCK]
@@ -317,35 +333,53 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
uuid = models.UUIDField(default=uuid.uuid4)
name = models.CharField(_("Name"), max_length=200)
- warehouse_type = models.ForeignKey(WarehouseType,
- verbose_name=_("Warehouse type"))
+ warehouse_type = models.ForeignKey(WarehouseType, verbose_name=_("Warehouse type"))
person_in_charge = models.ForeignKey(
- "ishtar_common.Person", on_delete=models.SET_NULL,
- related_name='warehouse_in_charge',
- verbose_name=_("Person in charge"), null=True, blank=True)
+ "ishtar_common.Person",
+ on_delete=models.SET_NULL,
+ related_name="warehouse_in_charge",
+ verbose_name=_("Person in charge"),
+ null=True,
+ blank=True,
+ )
organization = models.ForeignKey(
- "ishtar_common.Organization", blank=True, null=True,
- related_name='warehouses', verbose_name=_("Organization"),
- on_delete=models.SET_NULL)
+ "ishtar_common.Organization",
+ blank=True,
+ null=True,
+ related_name="warehouses",
+ verbose_name=_("Organization"),
+ on_delete=models.SET_NULL,
+ )
comment = models.TextField(_("Comment"), blank=True, default="")
associated_divisions = models.ManyToManyField(
- 'WarehouseDivision', verbose_name=_("Divisions"), blank=True,
- through='WarehouseDivisionLink'
+ "WarehouseDivision",
+ verbose_name=_("Divisions"),
+ blank=True,
+ through="WarehouseDivisionLink",
)
documents = models.ManyToManyField(
- "ishtar_common.Document", related_name='warehouses',
+ "ishtar_common.Document",
+ related_name="warehouses",
verbose_name=_("Documents"),
- blank=True)
+ blank=True,
+ )
main_image = models.ForeignKey(
- "ishtar_common.Document", related_name='main_image_warehouses',
+ "ishtar_common.Document",
+ related_name="main_image_warehouses",
on_delete=models.SET_NULL,
- verbose_name=_("Main image"), blank=True, null=True)
+ verbose_name=_("Main image"),
+ blank=True,
+ null=True,
+ )
external_id = models.TextField(_("External ID"), blank=True, default="")
auto_external_id = models.BooleanField(
- _("External ID is set automatically"), default=False)
+ _("External ID is set automatically"), default=False
+ )
max_division_number = models.IntegerField(
- _("Maximum number of divisions"), default=0,
- help_text=_("Automatically generated"))
+ _("Maximum number of divisions"),
+ default=0,
+ help_text=_("Automatically generated"),
+ )
SUB_ADDRESSES = ["organization", "person_in_charge"]
class Meta:
@@ -359,7 +393,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
("delete_own_warehouse", "Can delete own Warehouse"),
)
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
def __str__(self):
@@ -373,8 +407,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
:param place: place number
:return: container type, other location or None, None
"""
- q = WarehouseDivisionLink.objects.filter(
- warehouse=self).order_by('order')
+ q = WarehouseDivisionLink.objects.filter(warehouse=self).order_by("order")
previous_container_types = []
for idx, division_link in enumerate(q.all()):
if idx == place:
@@ -388,6 +421,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
@post_importer_action
def add_localisations(self, context, value):
self._add_localisations(context, value)
+
add_localisations.post_save = True
def _add_localisations(self, context, value, return_errors=False):
@@ -415,17 +449,20 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
values = value.split(";")
- divisions = list(WarehouseDivisionLink.objects.filter(
- warehouse=self).order_by('order'))
+ divisions = list(
+ WarehouseDivisionLink.objects.filter(warehouse=self).order_by("order")
+ )
parent = None
for idx, value in enumerate(values):
if idx >= len(divisions):
if return_errors:
return str(
- _("{} values for only {} default divisions set for "
- "warehouse {}")).format(
- len(values), len(divisions), self.name)
+ _(
+ "{} values for only {} default divisions set for "
+ "warehouse {}"
+ )
+ ).format(len(values), len(divisions), self.name)
return
value = value.replace(TMP_SEMI_COLON, ";").strip()
if not value or value == "-":
@@ -434,7 +471,8 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
location=self,
reference=value,
container_type_id=divisions[idx].container_type_id,
- parent=parent)
+ parent=parent,
+ )
if created and import_object:
parent.imports.add(import_object)
@@ -443,7 +481,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
return self.name
def natural_key(self):
- return (self.uuid, )
+ return (self.uuid,)
def _get_base_image_path(self):
return "{}/{}".format(self.SLUG, self.external_id)
@@ -462,8 +500,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
orga_type = q.all()[0]
else:
orga_type, __ = OrganizationType.objects.get_or_create(
- txt_idx="undefined",
- defaults={"label": _("Undefined")}
+ txt_idx="undefined", defaults={"label": _("Undefined")}
)
dct_orga["organization_type"] = orga_type
dct_orga["name"] = self.name
@@ -491,53 +528,52 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
@property
def default_location_types(self):
return [
- wd.container_type.label
- for wd in WarehouseDivisionLink.objects.filter(
- warehouse=self).order_by('order').all() if wd.container_type
+ wd.container_type.label
+ for wd in WarehouseDivisionLink.objects.filter(warehouse=self)
+ .order_by("order")
+ .all()
+ if wd.container_type
]
@property
def associated_filename(self):
- return datetime.date.today().strftime('%Y-%m-%d') + '-' + \
- slugify(str(self))
+ return datetime.date.today().strftime("%Y-%m-%d") + "-" + slugify(str(self))
@classmethod
def get_query_owns(cls, ishtaruser):
- return cls._construct_query_own(
- '', cls._get_query_owns_dicts(ishtaruser))
+ return cls._construct_query_own("", cls._get_query_owns_dicts(ishtaruser))
@classmethod
def _get_query_owns_dicts(cls, ishtaruser):
- return [{'person_in_charge__ishtaruser': ishtaruser}]
+ return [{"person_in_charge__ishtaruser": ishtaruser}]
def merge(self, item, keep_old=False):
# do not recreate missing divisions
available_divisions = [
- wd.division
- for wd in WarehouseDivisionLink.objects.filter(warehouse=self)
+ wd.division for wd in WarehouseDivisionLink.objects.filter(warehouse=self)
]
for container in list(item.containers.all()):
container.location = self
container.save()
- for loca in ContainerLocalisation.objects.filter(
- container=container).all():
+ for loca in ContainerLocalisation.objects.filter(container=container).all():
if loca.division.division in available_divisions:
div = WarehouseDivisionLink.objects.get(
- warehouse=self,
- division=loca.division.division
+ warehouse=self, division=loca.division.division
)
ContainerLocalisation.objects.create(
- container=container, division=div,
- reference=loca.reference
+ container=container, division=div, reference=loca.reference
)
loca.delete()
container.save() # force label regeneration
for container in list(item.containers.all()):
- if Container.objects.filter(index=container.index,
- location=self).count():
- container.index = Container.objects.filter(
- location=self).exclude(id=container.id).all().aggregate(
- Max("index"))["index__max"] + 1
+ if Container.objects.filter(index=container.index, location=self).count():
+ container.index = (
+ Container.objects.filter(location=self)
+ .exclude(id=container.id)
+ .all()
+ .aggregate(Max("index"))["index__max"]
+ + 1
+ )
container.location = self
container.save()
for wdiv in WarehouseDivisionLink.objects.filter(warehouse=item).all():
@@ -550,7 +586,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
self.skip_history_when_saving = True
if not self.external_id or self.auto_external_id:
- external_id = get_generated_id('warehouse_external_id', self)
+ external_id = get_generated_id("warehouse_external_id", self)
if external_id != self.external_id:
self.auto_external_id = True
self.external_id = external_id
@@ -559,8 +595,7 @@ class Warehouse(Address, DocumentItem, GeoItem, CompleteIdentifierItem,
return
-m2m_changed.connect(document_attached_changed,
- sender=Warehouse.documents.through)
+m2m_changed.connect(document_attached_changed, sender=Warehouse.documents.through)
post_save.connect(cached_label_and_geo_changed, sender=Warehouse)
@@ -577,28 +612,35 @@ post_delete.connect(post_save_cache, sender=WarehouseDivision)
class WarehouseDivisionLinkManager(models.Manager):
def get_by_natural_key(self, warehouse, container_type):
- return self.get(warehouse__uuid=warehouse,
- container_type__txt_idx=container_type)
+ return self.get(
+ warehouse__uuid=warehouse, container_type__txt_idx=container_type
+ )
class ContainerType(GeneralType):
stationary = models.BooleanField(
- _("Stationary"), default=False,
- help_text=_("Container that will not usually be moved. Ex: building, "
- "room, span, shelf."))
+ _("Stationary"),
+ default=False,
+ help_text=_(
+ "Container that will not usually be moved. Ex: building, "
+ "room, span, shelf."
+ ),
+ )
length = models.IntegerField(_("Length (mm)"), blank=True, null=True)
width = models.IntegerField(_("Width (mm)"), blank=True, null=True)
height = models.IntegerField(_("Height (mm)"), blank=True, null=True)
volume = models.FloatField(_("Volume (l)"), blank=True, null=True)
tare_weight = models.FloatField(_("Tare weight (g)"), blank=True, null=True)
- reference = models.CharField(_("Ref."), max_length=300, blank=True,
- null=True)
+ reference = models.CharField(_("Ref."), max_length=300, blank=True, null=True)
order = models.IntegerField(_("Order"), default=10)
class Meta:
verbose_name = _("Container type")
verbose_name_plural = _("Container types")
- ordering = ('order', 'label',)
+ ordering = (
+ "order",
+ "label",
+ )
post_save.connect(post_save_cache, sender=ContainerType)
@@ -608,18 +650,18 @@ post_delete.connect(post_save_cache, sender=ContainerType)
class WarehouseDivisionLink(models.Model):
RELATED_SET_NAME = "divisions"
RELATED_ATTRS = ["order", "container_type"]
- RELATIVE_MODELS = {Warehouse: 'warehouse'}
- warehouse = models.ForeignKey(Warehouse, related_name='divisions')
+ RELATIVE_MODELS = {Warehouse: "warehouse"}
+ warehouse = models.ForeignKey(Warehouse, related_name="divisions")
container_type = models.ForeignKey(ContainerType, blank=True, null=True)
division = models.ForeignKey(
- WarehouseDivision, help_text=_("Deprecated - do not use"),
- blank=True, null=True)
+ WarehouseDivision, help_text=_("Deprecated - do not use"), blank=True, null=True
+ )
order = models.IntegerField(_("Order"), default=10)
objects = WarehouseDivisionLinkManager()
class Meta:
- ordering = ('warehouse', 'order')
- unique_together = ('warehouse', 'division')
+ ordering = ("warehouse", "order")
+ unique_together = ("warehouse", "division")
def __str__(self):
return "{} - {}".format(self.warehouse, self.container_type)
@@ -682,31 +724,47 @@ class ContainerTree(models.Model):
DROP VIEW IF EXISTS containers_tree;
"""
container = models.OneToOneField(
- "archaeological_warehouse.Container", verbose_name=_("Container"),
- related_name="container_tree_child", primary_key=True)
+ "archaeological_warehouse.Container",
+ verbose_name=_("Container"),
+ related_name="container_tree_child",
+ primary_key=True,
+ )
container_parent = models.ForeignKey(
"archaeological_warehouse.Container",
verbose_name=_("Container parent"),
- related_name="container_tree_parent")
+ related_name="container_tree_parent",
+ )
class Meta:
managed = False
- db_table = 'containers_tree'
-
-
-class Container(DocumentItem, Merge, LightHistorizedItem,
- CompleteIdentifierItem, GeoItem, OwnPerms, MainItem,
- DivisionContainer, ValueGetter):
- SLUG = 'container'
+ db_table = "containers_tree"
+
+
+class Container(
+ DocumentItem,
+ Merge,
+ LightHistorizedItem,
+ CompleteIdentifierItem,
+ GeoItem,
+ OwnPerms,
+ MainItem,
+ DivisionContainer,
+ ValueGetter,
+):
+ SLUG = "container"
APP = "archaeological-warehouse"
MODEL = "container"
- SHOW_URL = 'show-container'
- DELETE_URL = 'delete-container'
+ SHOW_URL = "show-container"
+ DELETE_URL = "delete-container"
NEW_QUERY_ENGINE = True
- TABLE_COLS = ['container_type__label', 'reference',
- 'location__name',
- 'cached_division', 'old_reference']
- IMAGE_PREFIX = 'containers/'
+ TABLE_COLS = [
+ "container_type__label",
+ "reference",
+ "location__name",
+ "cached_division",
+ "old_reference",
+ ]
+ IMAGE_PREFIX = "containers/"
BASE_SEARCH_VECTORS = [
SearchVectorConfig("reference"),
SearchVectorConfig("container_type__label"),
@@ -720,210 +778,208 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
]
PARENT_SEARCH_VECTORS = ["parent"]
- STATISTIC_MODALITIES_OPTIONS = OrderedDict([
- ("location__name", _("Location (warehouse)")),
- ("responsibility__name", _("Responsibility (warehouse)")),
- ('finds__base_finds__context_record__operation__cached_label',
- _("Operation")),
- ])
- STATISTIC_MODALITIES = [
- key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]
+ STATISTIC_MODALITIES_OPTIONS = OrderedDict(
+ [
+ ("location__name", _("Location (warehouse)")),
+ ("responsibility__name", _("Responsibility (warehouse)")),
+ (
+ "finds__base_finds__context_record__operation__cached_label",
+ _("Operation"),
+ ),
+ ]
+ )
+ STATISTIC_MODALITIES = [key for key, lbl in STATISTIC_MODALITIES_OPTIONS.items()]
GET_VALUES_EXCLUDE_FIELDS = ValueGetter.GET_VALUES_EXCLUDE_FIELDS + [
- "inside_container", "parent"]
+ "inside_container",
+ "parent",
+ ]
# search parameters
EXTRA_REQUEST_KEYS = {
- 'location': 'location__pk',
- 'location__name': "location__name",
- 'location_id': 'location__pk',
- 'responsibility_id': 'responsibility__pk',
- 'container_type': 'container_type__pk',
- 'reference': 'reference__icontains',
- 'old_reference': 'old_reference__icontains',
- 'finds__base_finds__context_record__operation':
- 'finds__base_finds__context_record__operation',
- 'finds__base_finds__context_record':
- 'finds__base_finds__context_record',
- 'finds': 'finds',
- 'container_type__label': 'container_type__label',
-
+ "location": "location__pk",
+ "location__name": "location__name",
+ "location_id": "location__pk",
+ "responsibility_id": "responsibility__pk",
+ "container_type": "container_type__pk",
+ "reference": "reference__icontains",
+ "old_reference": "old_reference__icontains",
+ "finds__base_finds__context_record__operation": "finds__base_finds__context_record__operation",
+ "finds__base_finds__context_record": "finds__base_finds__context_record",
+ "finds": "finds",
+ "container_type__label": "container_type__label",
# dynamic tables
- 'container_tree_child__container_parent__id':
- 'container_tree_child__container_parent__id'
+ "container_tree_child__container_parent__id": "container_tree_child__container_parent__id",
}
COL_LABELS = {
- 'cached_location': _("Location - index"),
- 'cached_division': _("Precise localisation"),
- 'container_type__label': _("Type"),
- "location__name": _("Warehouse")
+ "cached_location": _("Location - index"),
+ "cached_division": _("Precise localisation"),
+ "container_type__label": _("Type"),
+ "location__name": _("Warehouse"),
}
GEO_LABEL = "cached_label"
- CACHED_LABELS = ['cached_division', 'cached_label', 'cached_location',
- 'cached_weight']
+ CACHED_LABELS = [
+ "cached_division",
+ "cached_label",
+ "cached_location",
+ "cached_weight",
+ ]
# alternative names of fields for searches
ALT_NAMES = {
- 'location_name': SearchAltName(
- pgettext_lazy("key for text search", "location"),
- 'location__name__iexact'
+ "location_name": SearchAltName(
+ pgettext_lazy("key for text search", "location"), "location__name__iexact"
),
- 'responsibility_name': SearchAltName(
+ "responsibility_name": SearchAltName(
pgettext_lazy("key for text search", "responsibility"),
- 'responsibility__name__iexact'
+ "responsibility__name__iexact",
),
- 'container_type': SearchAltName(
+ "container_type": SearchAltName(
pgettext_lazy("key for text search", "type"),
- 'container_type__label__iexact'
+ "container_type__label__iexact",
),
- 'reference': SearchAltName(
- pgettext_lazy("key for text search", "reference"),
- 'reference__iexact'
+ "reference": SearchAltName(
+ pgettext_lazy("key for text search", "reference"), "reference__iexact"
),
- 'old_reference': SearchAltName(
+ "old_reference": SearchAltName(
pgettext_lazy("key for text search", "old-reference"),
- 'old_reference__iexact'
+ "old_reference__iexact",
),
- 'comment': SearchAltName(
- pgettext_lazy("key for text search", "comment"),
- 'comment__iexact'
+ "comment": SearchAltName(
+ pgettext_lazy("key for text search", "comment"), "comment__iexact"
),
- 'operation_town':
- SearchAltName(
- pgettext_lazy("key for text search", "operation-town"),
- 'finds__base_finds__context_record__operation__'
- 'towns__cached_label__iexact'
- ),
- 'operation_scientist':
- SearchAltName(
- pgettext_lazy("key for text search", "operation-scientist"),
- 'finds__base_finds__context_record__operation__'
- 'scientist__cached_label__iexact'
- ),
- 'code_patriarche':
- SearchAltName(
- pgettext_lazy("key for text search", "code-patriarche"),
- 'finds__base_finds__context_record__operation__'
- 'code_patriarche__iexact'
- ),
- 'archaeological_sites':
- SearchAltName(
- pgettext_lazy("key for text search", "site"),
- 'finds__base_finds__context_record__operation__'
- 'archaeological_sites__cached_label__icontains'),
- 'archaeological_sites_name':
- SearchAltName(
- pgettext_lazy("key for text search", "site-name"),
- 'finds__base_finds__context_record__operation__'
- 'archaeological_sites__name__iexact'),
- 'archaeological_sites_context_record':
- SearchAltName(
- pgettext_lazy("key for text search", "context-record-site"),
- 'finds__base_finds__context_record__archaeological_site__'
- 'cached_label__icontains'),
- 'archaeological_sites_context_record_name':
- SearchAltName(
- pgettext_lazy("key for text search",
- "context-record-site-name"),
- 'finds__base_finds__context_record__archaeological_site__'
- 'name__iexact'),
- 'context_record':
- SearchAltName(
- pgettext_lazy("key for text search", "context-record"),
- 'finds__base_finds__context_record__cached_label__icontains'),
- 'find_label':
- SearchAltName(
- pgettext_lazy("key for text search", "find-label"),
- 'finds__label__icontains'),
- 'find_denomination':
- SearchAltName(
- pgettext_lazy("key for text search", "find-denomination"),
- 'finds__denomination__icontains'),
- 'material_types':
- SearchAltName(
- pgettext_lazy("key for text search", "material"),
- 'finds__material_types__label__iexact'),
- 'object_types':
- SearchAltName(
- pgettext_lazy("key for text search", "object-type"),
- 'finds__object_types__label__iexact'),
- 'preservation_to_considers':
- SearchAltName(
- pgettext_lazy("key for text search", "preservation"),
- 'finds__preservation_to_considers__label__iexact'),
- 'conservatory_state':
- SearchAltName(
- pgettext_lazy("key for text search", "conservatory"),
- 'finds__conservatory_state__label__iexact'),
- 'integrities':
- SearchAltName(
- pgettext_lazy("key for text search", "integrity"),
- 'finds__integrities__label__iexact'),
- 'remarkabilities':
- SearchAltName(
- pgettext_lazy("key for text search", "remarkability"),
- 'finds__remarkabilities__label__iexact'),
- 'alterations':
- SearchAltName(
- pgettext_lazy("key for text search", "alterations"),
- 'finds__alterations__label__iexact'),
- 'alteration_causes':
- SearchAltName(
- pgettext_lazy("key for text search", "alteration-causes"),
- 'finds__alteration_causes__label__iexact'),
- 'treatment_emergency':
- SearchAltName(
- pgettext_lazy("key for text search", "treatment-emergency"),
- 'finds__treatment_emergency__label__iexact'),
- 'description':
- SearchAltName(
- pgettext_lazy("key for text search", "find-description"),
- 'finds__description__iexact'),
- 'empty': SearchAltName(
- pgettext_lazy("key for text search", "empty"),
- 'finds'
+ "operation_town": SearchAltName(
+ pgettext_lazy("key for text search", "operation-town"),
+ "finds__base_finds__context_record__operation__"
+ "towns__cached_label__iexact",
+ ),
+ "operation_scientist": SearchAltName(
+ pgettext_lazy("key for text search", "operation-scientist"),
+ "finds__base_finds__context_record__operation__"
+ "scientist__cached_label__iexact",
+ ),
+ "code_patriarche": SearchAltName(
+ pgettext_lazy("key for text search", "code-patriarche"),
+ "finds__base_finds__context_record__operation__" "code_patriarche__iexact",
+ ),
+ "archaeological_sites": SearchAltName(
+ pgettext_lazy("key for text search", "site"),
+ "finds__base_finds__context_record__operation__"
+ "archaeological_sites__cached_label__icontains",
+ ),
+ "archaeological_sites_name": SearchAltName(
+ pgettext_lazy("key for text search", "site-name"),
+ "finds__base_finds__context_record__operation__"
+ "archaeological_sites__name__iexact",
+ ),
+ "archaeological_sites_context_record": SearchAltName(
+ pgettext_lazy("key for text search", "context-record-site"),
+ "finds__base_finds__context_record__archaeological_site__"
+ "cached_label__icontains",
+ ),
+ "archaeological_sites_context_record_name": SearchAltName(
+ pgettext_lazy("key for text search", "context-record-site-name"),
+ "finds__base_finds__context_record__archaeological_site__" "name__iexact",
+ ),
+ "context_record": SearchAltName(
+ pgettext_lazy("key for text search", "context-record"),
+ "finds__base_finds__context_record__cached_label__icontains",
+ ),
+ "find_label": SearchAltName(
+ pgettext_lazy("key for text search", "find-label"),
+ "finds__label__icontains",
+ ),
+ "find_denomination": SearchAltName(
+ pgettext_lazy("key for text search", "find-denomination"),
+ "finds__denomination__icontains",
+ ),
+ "material_types": SearchAltName(
+ pgettext_lazy("key for text search", "material"),
+ "finds__material_types__label__iexact",
+ ),
+ "object_types": SearchAltName(
+ pgettext_lazy("key for text search", "object-type"),
+ "finds__object_types__label__iexact",
+ ),
+ "preservation_to_considers": SearchAltName(
+ pgettext_lazy("key for text search", "preservation"),
+ "finds__preservation_to_considers__label__iexact",
+ ),
+ "conservatory_state": SearchAltName(
+ pgettext_lazy("key for text search", "conservatory"),
+ "finds__conservatory_state__label__iexact",
+ ),
+ "integrities": SearchAltName(
+ pgettext_lazy("key for text search", "integrity"),
+ "finds__integrities__label__iexact",
+ ),
+ "remarkabilities": SearchAltName(
+ pgettext_lazy("key for text search", "remarkability"),
+ "finds__remarkabilities__label__iexact",
+ ),
+ "alterations": SearchAltName(
+ pgettext_lazy("key for text search", "alterations"),
+ "finds__alterations__label__iexact",
+ ),
+ "alteration_causes": SearchAltName(
+ pgettext_lazy("key for text search", "alteration-causes"),
+ "finds__alteration_causes__label__iexact",
),
- 'contain_containers': SearchAltName(
+ "treatment_emergency": SearchAltName(
+ pgettext_lazy("key for text search", "treatment-emergency"),
+ "finds__treatment_emergency__label__iexact",
+ ),
+ "description": SearchAltName(
+ pgettext_lazy("key for text search", "find-description"),
+ "finds__description__iexact",
+ ),
+ "empty": SearchAltName(pgettext_lazy("key for text search", "empty"), "finds"),
+ "contain_containers": SearchAltName(
pgettext_lazy("key for text search", "contain-containers"),
- 'children__isnull'
+ "children__isnull",
),
- 'is_stationary': SearchAltName(
+ "is_stationary": SearchAltName(
pgettext_lazy("key for text search", "is-stationary"),
- 'container_type__stationary'
- )
+ "container_type__stationary",
+ ),
}
REVERSED_BOOL_FIELDS = [
- 'children__isnull',
- 'documents__image__isnull',
- 'documents__associated_file__isnull',
- 'documents__associated_url__isnull',
+ "children__isnull",
+ "documents__image__isnull",
+ "documents__associated_file__isnull",
+ "documents__associated_url__isnull",
]
- BOOL_FIELDS = ['container_type__stationary']
- REVERSED_MANY_COUNTED_FIELDS = ['finds', 'finds_ref']
+ BOOL_FIELDS = ["container_type__stationary"]
+ REVERSED_MANY_COUNTED_FIELDS = ["finds", "finds_ref"]
ALT_NAMES.update(LightHistorizedItem.ALT_NAMES)
ALT_NAMES.update(DocumentItem.ALT_NAMES)
DYNAMIC_REQUESTS = {
- 'division': DynamicRequest(
+ "division": DynamicRequest(
label=_("Division -"),
- app_name='archaeological_warehouse', model_name='WarehouseDivision',
- form_key='division',
- search_key=pgettext_lazy("key for text search",
- 'division'),
- type_query='division__division__division__txt_idx',
- search_query='division__reference__iexact'
+ app_name="archaeological_warehouse",
+ model_name="WarehouseDivision",
+ form_key="division",
+ search_key=pgettext_lazy("key for text search", "division"),
+ type_query="division__division__division__txt_idx",
+ search_query="division__reference__iexact",
),
}
QA_EDIT = QuickAction(
- url="container-qa-bulk-update", icon_class="fa fa-pencil",
- text=_("Bulk update"), target="many",
- rights=['change_container', 'change_own_container'])
+ url="container-qa-bulk-update",
+ icon_class="fa fa-pencil",
+ text=_("Bulk update"),
+ target="many",
+ rights=["change_container", "change_own_container"],
+ )
QA_LOCK = QuickAction(
- url="container-qa-lock", icon_class="fa fa-lock",
- text=_("Lock/Unlock"), target="many",
- rights=['change_container', 'change_own_container']
+ url="container-qa-lock",
+ icon_class="fa fa-lock",
+ text=_("Lock/Unlock"),
+ target="many",
+ rights=["change_container", "change_own_container"],
)
QUICK_ACTIONS = [QA_EDIT, QA_LOCK]
@@ -934,52 +990,76 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
# fields
uuid = models.UUIDField(default=uuid.uuid4)
location = models.ForeignKey(
- Warehouse, verbose_name=_("Location (warehouse)"),
- related_name='containers')
+ Warehouse, verbose_name=_("Location (warehouse)"), related_name="containers"
+ )
responsible = models.ForeignKey(
- Warehouse, verbose_name=_("Responsible warehouse"),
- related_name='owned_containers', blank=True, null=True,
- help_text=_("Deprecated - do not use")
+ Warehouse,
+ verbose_name=_("Responsible warehouse"),
+ related_name="owned_containers",
+ blank=True,
+ null=True,
+ help_text=_("Deprecated - do not use"),
)
responsibility = models.ForeignKey(
- Warehouse, verbose_name=_("Responsibility"),
- related_name='responsibilities', blank=True, null=True,
- help_text=_("Warehouse that owns the container")
+ Warehouse,
+ verbose_name=_("Responsibility"),
+ related_name="responsibilities",
+ blank=True,
+ null=True,
+ help_text=_("Warehouse that owns the container"),
+ )
+ container_type = models.ForeignKey(
+ ContainerType, verbose_name=_("Container type"), related_name="containers"
)
- container_type = models.ForeignKey(ContainerType,
- verbose_name=_("Container type"),
- related_name="containers")
reference = models.TextField(_("Container ref."))
comment = models.TextField(_("Comment"), blank=True, default="")
- cached_label = models.TextField(_("Localisation"), blank=True, default="",
- db_index=True)
- cached_location = models.TextField(_("Cached location"),
- blank=True, default="", db_index=True)
- cached_division = models.TextField(_("Cached division"),
- blank=True, default="", db_index=True)
- parent = models.ForeignKey("Container", verbose_name=_("Parent container"),
- on_delete=models.SET_NULL,
- related_name="children", blank=True, null=True)
- index = models.IntegerField(_("Container ID"), blank=True, null=True,
- db_index=True)
+ cached_label = models.TextField(
+ _("Localisation"), blank=True, default="", db_index=True
+ )
+ cached_location = models.TextField(
+ _("Cached location"), blank=True, default="", db_index=True
+ )
+ cached_division = models.TextField(
+ _("Cached division"), blank=True, default="", db_index=True
+ )
+ parent = models.ForeignKey(
+ "Container",
+ verbose_name=_("Parent container"),
+ on_delete=models.SET_NULL,
+ related_name="children",
+ blank=True,
+ null=True,
+ )
+ index = models.IntegerField(_("Container ID"), blank=True, null=True, db_index=True)
weight = models.FloatField(_("Measured weight (g)"), blank=True, null=True)
calculated_weight = models.FloatField(
- _("Calculated weight (g)"), blank=True, null=True)
+ _("Calculated weight (g)"), blank=True, null=True
+ )
cached_weight = models.FloatField(
- _("Cached weight (g)"), blank=True, null=True,
- help_text=_("Entered weight if available otherwise calculated weight.")
+ _("Cached weight (g)"),
+ blank=True,
+ null=True,
+ help_text=_("Entered weight if available otherwise calculated weight."),
)
old_reference = models.TextField(_("Old reference"), blank=True, default="")
external_id = models.TextField(_("External ID"), blank=True, default="")
auto_external_id = models.BooleanField(
- _("External ID is set automatically"), default=False)
+ _("External ID is set automatically"), default=False
+ )
documents = models.ManyToManyField(
- "ishtar_common.Document", related_name='containers',
- verbose_name=_("Documents"), blank=True)
+ "ishtar_common.Document",
+ related_name="containers",
+ verbose_name=_("Documents"),
+ blank=True,
+ )
main_image = models.ForeignKey(
- "ishtar_common.Document", related_name='main_image_containers',
+ "ishtar_common.Document",
+ related_name="main_image_containers",
on_delete=models.SET_NULL,
- verbose_name=_("Main image"), blank=True, null=True)
+ verbose_name=_("Main image"),
+ blank=True,
+ null=True,
+ )
DISABLE_POLYGONS = False
MERGE_ATTRIBUTE = "get_merge_key"
@@ -988,9 +1068,12 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
class Meta:
verbose_name = _("Container")
verbose_name_plural = _("Containers")
- ordering = ('location', 'index', 'cached_label',)
- unique_together = [('location', 'container_type', 'parent',
- 'reference')]
+ ordering = (
+ "location",
+ "index",
+ "cached_label",
+ )
+ unique_together = [("location", "container_type", "parent", "reference")]
permissions = (
("view_container", "Can view all Containers"),
("view_own_container", "Can view own Container"),
@@ -999,7 +1082,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
("delete_own_container", "Can delete own Container"),
)
indexes = [
- GinIndex(fields=['data']),
+ GinIndex(fields=["data"]),
]
def __str__(self):
@@ -1017,8 +1100,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
return depth
def get_max_division_number(self):
- return self.location.get_max_division_number() \
- - self.start_division_number
+ return self.location.get_max_division_number() - self.start_division_number
@property
def number_of_finds_hosted(self):
@@ -1049,13 +1131,12 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
return self.parent.external_id
def natural_key(self):
- return (self.uuid, )
+ return (self.uuid,)
@classmethod
@pre_importer_action
def import_get_location(cls, context, value):
- if context.get("container_type", None) and context.get(
- "reference", None):
+ if context.get("container_type", None) and context.get("reference", None):
try:
context["location"] = Warehouse.objects.get(external_id=value)
return
@@ -1085,15 +1166,23 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
:return: True if calculated weight is changed
"""
profile = get_current_profile()
- if profile.calculate_weight_on_full and self.finds.filter(
- weight__isnull=True).count():
+ if (
+ profile.calculate_weight_on_full
+ and self.finds.filter(weight__isnull=True).count()
+ ):
weight = None
else:
weight = sum(
- w for w in self.finds.filter(weight__isnull=False).values_list(
- "weight", flat=True).all())
- weight += self.container_type.tare_weight \
- if self.container_type.tare_weight else 0
+ w
+ for w in self.finds.filter(weight__isnull=False)
+ .values_list("weight", flat=True)
+ .all()
+ )
+ weight += (
+ self.container_type.tare_weight
+ if self.container_type.tare_weight
+ else 0
+ )
if weight != self.calculated_weight:
self.calculated_weight = weight
return True
@@ -1103,8 +1192,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
def get_calculated_weight_percent(self):
if not self.calculated_weight or not self.weight:
return 0
- return (self.calculated_weight
- - self.weight) / self.calculated_weight * 100
+ return (self.calculated_weight - self.weight) / self.calculated_weight * 100
@property
def get_cached_division(self):
@@ -1113,8 +1201,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
@property
def get_merge_key(self):
try:
- return str(self.location.uuid) + "|" + \
- self._generate_cached_division()
+ return str(self.location.uuid) + "|" + self._generate_cached_division()
except Warehouse.DoesNotExist:
return
@@ -1123,11 +1210,13 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
try:
doc = Document.objects.get(**{key: value})
except Document.DoesNotExist:
- raise ImporterError(str(_("Document with {}: {} does not "
- "exists")).format(key, value))
+ raise ImporterError(
+ str(_("Document with {}: {} does not " "exists")).format(key, value)
+ )
except Document.MultipleObjectsReturned:
raise ImporterError(
- str(_("Multiple document with {}: {}")).format(key, value))
+ str(_("Multiple document with {}: {}")).format(key, value)
+ )
doc.container_id = self.pk
doc.container_ref_id = self.pk
doc.skip_history_when_saving = True
@@ -1136,16 +1225,19 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
@post_importer_action
def put_document_by_external_id(self, context, value):
self.put_document_by_key(value, "external_id")
+
put_document_by_external_id.post_save = True
@post_importer_action
def put_document_by_reference(self, context, value):
self.put_document_by_key(value, "reference")
+
put_document_by_reference.post_save = True
@post_importer_action
def put_document_by_complete_identifier(self, context, value):
self.put_document_by_key(value, "complete_identifier")
+
put_document_by_complete_identifier.post_save = True
def _generate_cached_division(self):
@@ -1163,8 +1255,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
for loca in reversed(parents)
]
try:
- locas.append("{} {}".format(self.container_type.name,
- self.reference))
+ locas.append("{} {}".format(self.container_type.name, self.reference))
except ObjectDoesNotExist: # generate too early on item creation
pass
return " | ".join(locas)
@@ -1174,8 +1265,9 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
@classmethod
def _change_child_location(cls, parent):
- for child in cls.objects.filter(
- parent=parent).exclude(location=parent.location).all():
+ for child in (
+ cls.objects.filter(parent=parent).exclude(location=parent.location).all()
+ ):
if child.location != parent.location:
child.location = parent.location
child.save()
@@ -1198,13 +1290,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
child.parent = self
child.save()
self._change_child_location(self)
- super(Container, self).merge(item, keep_old=keep_old,
- exclude_fields=exclude_fields)
+ super(Container, self).merge(
+ item, keep_old=keep_old, exclude_fields=exclude_fields
+ )
@classmethod
def get_query_owns(cls, ishtaruser):
- return Q(history_creator=ishtaruser.user_ptr) | \
- Q(location__person_in_charge__ishtaruser=ishtaruser)
+ return Q(history_creator=ishtaruser.user_ptr) | Q(
+ location__person_in_charge__ishtaruser=ishtaruser
+ )
def get_precise_points(self):
precise_points = super(Container, self).get_precise_points()
@@ -1232,7 +1326,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
@property
def associated_filename(self):
- filename = datetime.date.today().strftime('%Y-%m-%d')
+ filename = datetime.date.today().strftime("%Y-%m-%d")
filename += "-" + self.reference
filename += "-" + self.location.name
filename += "-" + str(self.index)
@@ -1324,8 +1418,10 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
error_msg = str(NO_DIVISION_ERROR).format(place + 1, self.location)
- current_container_type, previous_container_types = \
- self.location.get_container_type_by_place(place)
+ (
+ current_container_type,
+ previous_container_types,
+ ) = self.location.get_container_type_by_place(place)
if not current_container_type:
# no division link set at this place
if return_errors:
@@ -1349,7 +1445,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
"reference": value,
"container_type": current_container_type,
"parent": current_parent,
- "location": self.location
+ "location": self.location,
}
q = Container.objects.filter(**dct)
if q.count():
@@ -1358,8 +1454,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
if static:
if return_errors:
error_msg = str(
- _("The division {} {} do not exist for the "
- "location {}.")
+ _("The division {} {} do not exist for the " "location {}.")
).format(current_container_type, value, self.location)
return None, error_msg
return
@@ -1376,103 +1471,128 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
@post_importer_action
def set_localisation_1(self, context, value):
return self.set_localisation(0, value)
+
set_localisation_1.post_save = True
@post_importer_action
def set_localisation_2(self, context, value):
return self.set_localisation(1, value)
+
set_localisation_2.post_save = True
@post_importer_action
def set_localisation_3(self, context, value):
return self.set_localisation(2, value)
+
set_localisation_3.post_save = True
@post_importer_action
def set_localisation_4(self, context, value):
return self.set_localisation(3, value)
+
set_localisation_4.post_save = True
@post_importer_action
def set_localisation_5(self, context, value):
return self.set_localisation(4, value)
+
set_localisation_5.post_save = True
@post_importer_action
def set_localisation_6(self, context, value):
return self.set_localisation(5, value)
+
set_localisation_6.post_save = True
@post_importer_action
def set_localisation_7(self, context, value):
return self.set_localisation(6, value)
+
set_localisation_7.post_save = True
@post_importer_action
def set_localisation_8(self, context, value):
return self.set_localisation(7, value)
+
set_localisation_8.post_save = True
@post_importer_action
def set_localisation_9(self, context, value):
return self.set_localisation(8, value)
+
set_localisation_9.post_save = True
@post_importer_action
def set_static_localisation_1(self, context, value):
return self.set_static_localisation(0, value)
+
set_static_localisation_1.post_save = True
@post_importer_action
def set_static_localisation_2(self, context, value):
return self.set_static_localisation(1, value)
+
set_static_localisation_2.post_save = True
@post_importer_action
def set_static_localisation_3(self, context, value):
return self.set_static_localisation(2, value)
+
set_static_localisation_3.post_save = True
@post_importer_action
def set_static_localisation_4(self, context, value):
return self.set_static_localisation(3, value)
+
set_static_localisation_4.post_save = True
@post_importer_action
def set_static_localisation_5(self, context, value):
return self.set_static_localisation(4, value)
+
set_static_localisation_5.post_save = True
@post_importer_action
def set_static_localisation_6(self, context, value):
return self.set_static_localisation(5, value)
+
set_static_localisation_6.post_save = True
@post_importer_action
def set_static_localisation_7(self, context, value):
return self.set_static_localisation(6, value)
+
set_static_localisation_7.post_save = True
@post_importer_action
def set_static_localisation_8(self, context, value):
return self.set_static_localisation(7, value)
+
set_static_localisation_8.post_save = True
@post_importer_action
def set_static_localisation_9(self, context, value):
return self.set_static_localisation(8, value)
+
set_static_localisation_9.post_save = True
DOC_VALUES = [
- ("operation_", _("Associated operation - use it with caution, "
- "only return the first found operation")),
- ("context_record_",
- _("Associated context record - use it with caution, "
- "only return the first found context_record")),
- ("material_types",
- _("Material types inside the container - string")),
- ("material_types_code",
- _("Material types code - string")),
+ (
+ "operation_",
+ _(
+ "Associated operation - use it with caution, "
+ "only return the first found operation"
+ ),
+ ),
+ (
+ "context_record_",
+ _(
+ "Associated context record - use it with caution, "
+ "only return the first found context_record"
+ ),
+ ),
+ ("material_types", _("Material types inside the container - string")),
+ ("material_types_code", _("Material types code - string")),
("finds", _("List of associated finds")),
]
@@ -1482,8 +1602,8 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
"""
materials = set()
for material in self.finds.exclude(
- material_types__code__isnull=True).values_list(
- "material_types__code", flat=True):
+ material_types__code__isnull=True
+ ).values_list("material_types__code", flat=True):
materials.add(material)
return "|".join(sorted(materials))
@@ -1493,38 +1613,43 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
"""
materials = set()
for material in self.finds.exclude(
- material_types__label__isnull=True).values_list(
- "material_types__label", flat=True):
+ material_types__label__isnull=True
+ ).values_list("material_types__label", flat=True):
materials.add(material)
return ", ".join(sorted(materials))
- def get_values(self, prefix='', no_values=False, filtr=None, **kwargs):
+ def get_values(self, prefix="", no_values=False, filtr=None, **kwargs):
values = super(Container, self).get_values(
- 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 and \
- "finds" not in kwargs.get("exclude", []):
+ 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
+ and "finds" not in kwargs.get("exclude", [])
+ ):
kwargs["exclude"] = [prefix + "container", prefix + "container_ref"]
# prevent recursive call
- values[prefix + 'finds'] = [
- f.get_values(
- prefix=prefix, no_values=True, filtr=None, **kwargs)
- for f in self.finds.distinct().all()]
+ values[prefix + "finds"] = [
+ f.get_values(prefix=prefix, no_values=True, filtr=None, **kwargs)
+ for f in self.finds.distinct().all()
+ ]
if not self.finds.count():
return values
operation_in_filter = filtr and any(
- k for k in filtr if k.startswith(prefix + 'operation'))
+ k for k in filtr if k.startswith(prefix + "operation")
+ )
cr_in_filter = filtr and any(
- k for k in filtr if k.startswith(prefix + 'context_record'))
- 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 not from_find and (
- not filtr or operation_in_filter or cr_in_filter):
+ k for k in filtr if k.startswith(prefix + "context_record")
+ )
+ 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 not from_find and (not filtr or operation_in_filter or cr_in_filter):
# assume that only one operation is in this container...
# you should know what you are doing when using theses variables
f = self.finds.all()[0]
@@ -1534,15 +1659,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
if not filtr or cr_in_filter:
kwargs["exclude"] = [prefix + "operation"]
for k, v in cr.get_values(
- prefix=prefix, no_values=True, filtr=None,
- **kwargs).items():
- values[prefix + 'context_record_' + k] = v
+ prefix=prefix, no_values=True, filtr=None, **kwargs
+ ).items():
+ values[prefix + "context_record_" + k] = v
if not filtr or operation_in_filter:
kwargs["exclude"] = [prefix + "context_records"]
for k, v in cr.operation.get_values(
- prefix=prefix, no_values=True, filtr=None,
- **kwargs).items():
- values[prefix + 'operation_' + k] = v
+ prefix=prefix, no_values=True, filtr=None, **kwargs
+ ).items():
+ values[prefix + "operation_" + k] = v
return values
def get_extra_actions(self, request):
@@ -1551,11 +1676,17 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
"""
# url, base_text, icon, extra_text, extra css class, is a quick action
actions = super(Container, self).get_extra_actions(request)
- can_edit_find = self.can_do(request, 'change_find')
+ can_edit_find = self.can_do(request, "change_find")
if can_edit_find:
actions += [
- (reverse('container-add-treatment', args=[self.pk]),
- _("Add treatment"), "fa fa-flask", "", "", False),
+ (
+ reverse("container-add-treatment", args=[self.pk]),
+ _("Add treatment"),
+ "fa fa-flask",
+ "",
+ "",
+ False,
+ ),
]
return actions
@@ -1579,8 +1710,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
return
q = Container.objects.filter(location=self.location)
if q.count():
- self.index = int(
- q.all().aggregate(Max("index"))["index__max"]) + 1
+ self.index = int(q.all().aggregate(Max("index"))["index__max"]) + 1
else:
self.index = 1
if not self.cached_division:
@@ -1591,8 +1721,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
parent = self.parent_id
while parent:
number += 1
- parent = Container.objects.filter(pk=parent).values_list(
- "parent_id")[0][0]
+ parent = Container.objects.filter(pk=parent).values_list("parent_id")[0][0]
if number > self.location.max_division_number:
self.location.max_division_number = number
self.location.save()
@@ -1608,15 +1737,17 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
if not self.index and not self.container_type.stationary:
self.skip_history_when_saving = True
- q = Container.objects.filter(
- location=self.location
- ).exclude(pk=self.pk).order_by('-index')
+ q = (
+ Container.objects.filter(location=self.location)
+ .exclude(pk=self.pk)
+ .order_by("-index")
+ )
self.index = q.all()[0].index + 1 if q.count() else 1
updated = True
self.skip_history_when_saving = True
if not self.external_id or self.auto_external_id:
- external_id = get_generated_id('container_external_id', self)
+ external_id = get_generated_id("container_external_id", self)
if external_id != self.external_id:
updated = True
self.auto_external_id = True
@@ -1629,14 +1760,15 @@ class Container(DocumentItem, Merge, LightHistorizedItem,
# remove old location in warehouse
q = ContainerLocalisation.objects.filter(container=self).exclude(
- division__warehouse=self.location)
+ division__warehouse=self.location
+ )
for loca in q.all():
loca.delete()
def container_post_save(sender, **kwargs):
cached_label_and_geo_changed(sender=sender, **kwargs)
- #TODO: to be deleted???
+ # TODO: to be deleted???
"""
if not kwargs.get('instance'):
return
@@ -1657,8 +1789,7 @@ def container_post_save(sender, **kwargs):
def container_pre_delete(sender, **kwargs):
instance = kwargs["instance"]
- q = Container.objects.filter(
- container_tree_child__container_parent=instance)
+ q = Container.objects.filter(container_tree_child__container_parent=instance)
q.update(cached_division="")
@@ -1672,43 +1803,45 @@ def container_post_delete(sender, **kwargs):
post_save.connect(container_post_save, sender=Container)
pre_delete.connect(container_pre_delete, sender=Container)
post_delete.connect(container_post_delete, sender=Container)
-m2m_changed.connect(document_attached_changed,
- sender=Container.documents.through)
+m2m_changed.connect(document_attached_changed, sender=Container.documents.through)
class ContainerLocalisationManager(models.Manager):
- #TODO: to be deleted....
+ # TODO: to be deleted....
def get_by_natural_key(self, container, warehouse, container_type):
- return self.get(container__uuid=container,
- division__warehouse__uuid=warehouse,
- division__container_type__txt_idx=container_type)
+ return self.get(
+ container__uuid=container,
+ division__warehouse__uuid=warehouse,
+ division__container_type__txt_idx=container_type,
+ )
class ContainerLocalisation(models.Model):
- #TODO: to be deleted....
- container = models.ForeignKey(Container, verbose_name=_("Container"),
- related_name='division')
- division = models.ForeignKey(WarehouseDivisionLink,
- verbose_name=_("Division"))
- reference = models.CharField(_("Reference"), max_length=200, default='')
+ # TODO: to be deleted....
+ container = models.ForeignKey(
+ Container, verbose_name=_("Container"), related_name="division"
+ )
+ division = models.ForeignKey(WarehouseDivisionLink, verbose_name=_("Division"))
+ reference = models.CharField(_("Reference"), max_length=200, default="")
objects = ContainerLocalisationManager()
TO_BE_DELETED = True
class Meta:
verbose_name = _("Container localisation")
verbose_name_plural = _("Container localisations")
- ordering = ('container', 'division__order')
+ ordering = ("container", "division__order")
def __str__(self):
- return " - ".join((str(self.container), str(self.division),
- self.reference))
+ return " - ".join((str(self.container), str(self.division), self.reference))
def natural_key(self):
- return self.container.uuid, self.division.warehouse.uuid,\
- self.division.container_type.txt_idx
+ return (
+ self.container.uuid,
+ self.division.warehouse.uuid,
+ self.division.container_type.txt_idx,
+ )
def save(self, *args, **kwargs):
super(ContainerLocalisation, self).save(*args, **kwargs)
self.container.skip_history_when_saving = True
- cached_label_changed(Container, instance=self.container,
- force_update=True)
+ cached_label_changed(Container, instance=self.container, force_update=True)