summaryrefslogtreecommitdiff
path: root/archaeological_finds/models_finds.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2024-04-16 16:41:46 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2024-04-16 16:41:46 +0200
commit6e95beabf26ddd3d8de69e34dfbfb97bc1625d80 (patch)
tree364c2688b46f47d3ee9243e70cbaf5485e177b0f /archaeological_finds/models_finds.py
parent303a62efae3d3f568545c682649a29de1fb7fc83 (diff)
downloadIshtar-6e95beabf26ddd3d8de69e34dfbfb97bc1625d80.tar.bz2
Ishtar-6e95beabf26ddd3d8de69e34dfbfb97bc1625d80.zip
🗃️ museum module: new db fields, add admin
Diffstat (limited to 'archaeological_finds/models_finds.py')
-rw-r--r--archaeological_finds/models_finds.py275
1 files changed, 248 insertions, 27 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index cb431f7cc..6c086ea93 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -25,48 +25,52 @@ from django.apps import apps
from django.conf import settings
from django.contrib.gis.db import models
from django.contrib.postgres.indexes import GinIndex
-from django.db import connection
from django.db.models import Max, Q, F
from django.db.models.signals import m2m_changed, post_save, post_delete, pre_delete
from django.core.exceptions import ObjectDoesNotExist
from django.urls import reverse
-from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy
from ishtar_common.data_importer import post_importer_action, ImporterError
from ishtar_common.utils import (
cached_label_changed,
- post_save_geo,
+ get_generated_id,
m2m_historization_changed,
+ pgettext_lazy,
+ post_save_geo,
+ ugettext_lazy as _
)
from ishtar_common.alternative_configs import ALTERNATE_CONFIGS
-from ishtar_common.model_managers import ExternalIdManager, UUIDModelManager
+from ishtar_common.model_managers import UUIDModelManager
from ishtar_common.models import (
+ BaseHistorizedItem,
+ Basket,
+ BiographicalNote,
+ BulkUpdatedItem,
+ CompleteIdentifierItem,
Document,
+ DocumentItem,
+ document_attached_changed,
GeneralType,
+ GeoItem,
+ get_current_profile,
HierarchicalType,
- BaseHistorizedItem,
+ HistoryModel,
+ Imported,
+ IshtarSiteProfile,
LightHistorizedItem,
+ MainItem,
+ OrderedHierarchicalType,
+ OrderedType,
+ Organization,
OwnPerms,
- Imported,
Person,
- Basket,
post_save_cache,
- ValueGetter,
- get_current_profile,
- IshtarSiteProfile,
- BulkUpdatedItem,
QuickAction,
- MainItem,
- document_attached_changed,
- HistoryModel,
- DynamicRequest,
SearchAltName,
- CompleteIdentifierItem,
SearchVectorConfig,
- DocumentItem,
- GeoItem
+ ValueGetter,
)
from ishtar_common.models_common import HistoricalRecords, SerializeItem, \
GeoVectorData, geodata_attached_changed
@@ -296,6 +300,38 @@ post_save.connect(post_save_cache, sender=FunctionalArea)
post_delete.connect(post_save_cache, sender=FunctionalArea)
+class TechnicalAreaType(OrderedHierarchicalType):
+ class Meta:
+ verbose_name = _("Technical area type")
+ verbose_name_plural = _("Technical area types")
+ ordering = (
+ "order",
+ "parent__label",
+ "label",
+ )
+ ADMIN_SECTION = _("Finds")
+
+
+post_save.connect(post_save_cache, sender=TechnicalAreaType)
+post_delete.connect(post_save_cache, sender=TechnicalAreaType)
+
+
+class TechnicalProcessType(OrderedHierarchicalType):
+ class Meta:
+ verbose_name = _("Technical process type")
+ verbose_name_plural = _("Technical process types")
+ ordering = (
+ "order",
+ "parent__label",
+ "label",
+ )
+ ADMIN_SECTION = _("Finds")
+
+
+post_save.connect(post_save_cache, sender=TechnicalProcessType)
+post_delete.connect(post_save_cache, sender=TechnicalProcessType)
+
+
class ObjectTypeQualityType(GeneralType):
order = models.IntegerField(_("Order"), default=10)
@@ -381,6 +417,99 @@ post_save.connect(post_save_cache, sender=CheckedType)
post_delete.connect(post_save_cache, sender=CheckedType)
+class CollectionEntryModeType(OrderedHierarchicalType):
+ class Meta:
+ verbose_name = _("Collection entry mode type")
+ verbose_name_plural = _("Collection entry mode types")
+ ordering = (
+ "order",
+ "parent__label",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=CollectionEntryModeType)
+post_delete.connect(post_save_cache, sender=CollectionEntryModeType)
+
+
+class InventoryMarkingPresence(OrderedType):
+ class Meta:
+ verbose_name = _("Presence of inventory marking type")
+ verbose_name_plural = _("Presence of inventory marking types")
+ ordering = (
+ "order",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=InventoryMarkingPresence)
+post_delete.connect(post_save_cache, sender=InventoryMarkingPresence)
+
+
+class MarkingType(OrderedType):
+ class Meta:
+ verbose_name = _("Marking type")
+ verbose_name_plural = _("Marking types")
+ ordering = (
+ "order",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=MarkingType)
+post_delete.connect(post_save_cache, sender=MarkingType)
+
+
+class MuseumCollection(OrderedType):
+ class Meta:
+ verbose_name = _("Museum collection")
+ verbose_name_plural = _("Museum collections")
+ ordering = (
+ "order",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=MuseumCollection)
+post_delete.connect(post_save_cache, sender=MuseumCollection)
+
+
+class InventoryConformity(OrderedType):
+ class Meta:
+ verbose_name = _("Inventory conformity type")
+ verbose_name_plural = _("Inventory conformity types")
+ ordering = (
+ "order",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=InventoryConformity)
+post_delete.connect(post_save_cache, sender=InventoryConformity)
+
+
+class OriginalReproduction(OrderedType):
+ class Meta:
+ verbose_name = _("Original/reproduction type")
+ verbose_name_plural = _("Original/reproduction types")
+ ordering = (
+ "order",
+ "label",
+ )
+ ADMIN_SECTION = _("Museum")
+
+
+post_save.connect(post_save_cache, sender=OriginalReproduction)
+post_delete.connect(post_save_cache, sender=OriginalReproduction)
+
+
+
+
class BFBulkView(object):
CREATE_SQL = """
CREATE VIEW basefind_cached_bulk_update
@@ -1550,6 +1679,7 @@ class Find(
BASE_SEARCH_VECTORS = [
SearchVectorConfig("cached_label", "raw"),
SearchVectorConfig("index", "raw"),
+ SearchVectorConfig("cache_complete_museum_id", "raw"),
SearchVectorConfig("label", "raw"),
SearchVectorConfig("description", "local"),
SearchVectorConfig("mark"),
@@ -1668,6 +1798,7 @@ class Find(
"alteration_causes",
]
CACHED_LABELS = [
+ "cache_complete_museum_id",
"cached_label",
"cached_periods",
"cached_object_types",
@@ -1703,7 +1834,11 @@ class Find(
order = models.IntegerField(_("Order"), default=1)
label = models.TextField(_("Free ID"))
denomination = models.TextField(_("Denomination"), blank=True, default="")
- museum_id = models.TextField(_("Museum inventory number"), blank=True, default="")
+ # museum module IDs
+ museum_id_prefix = models.TextField(_("Museum ID prefix"), blank=True, default="")
+ museum_id = models.TextField(_("Museum ID"), blank=True, default="")
+ museum_id_suffix = models.TextField(_("Museum ID suffix"), blank=True, default="")
+ museum_id_comment = models.TextField(_("Comment on museum ID"), blank=True, default="")
laboratory_id = models.TextField(_("Laboratory ID"), blank=True, default="")
description = models.TextField(_("Description"), blank=True, default="")
decoration = models.TextField(_("Decoration"), blank=True, default="")
@@ -1731,6 +1866,12 @@ class Find(
_("Weight unit"), max_length=4, blank=True, null=True, choices=WEIGHT_UNIT
)
find_number = models.IntegerField(_("Number of remains"), blank=True, null=True)
+ min_number_of_individuals = models.IntegerField(
+ _("Minimum number of individuals (MNI)"), blank=True, null=True
+ )
+ quantity_comment = models.TextField(
+ _("Comment on quantity"), blank=True, default=""
+ )
upstream_treatment = models.ForeignKey(
"Treatment",
blank=True,
@@ -1783,7 +1924,19 @@ class Find(
)
functional_areas = models.ManyToManyField(
FunctionalArea,
- verbose_name=_("Functional area"),
+ verbose_name=_("Functional areas"),
+ related_name="find",
+ blank=True,
+ )
+ technical_areas = models.ManyToManyField(
+ TechnicalAreaType,
+ verbose_name=_("Technical areas"),
+ related_name="find",
+ blank=True,
+ )
+ technical_processes = models.ManyToManyField(
+ TechnicalProcessType,
+ verbose_name=_("Technical processes"),
related_name="find",
blank=True,
)
@@ -1805,9 +1958,6 @@ class Find(
related_name="find",
blank=True,
)
- min_number_of_individuals = models.IntegerField(
- _("Minimum number of individuals (MNI)"), blank=True, null=True
- )
length = models.FloatField(_("Length (cm)"), blank=True, null=True)
width = models.FloatField(_("Width (cm)"), blank=True, null=True)
height = models.FloatField(_("Height (cm)"), blank=True, null=True)
@@ -1841,14 +1991,72 @@ class Find(
check_date = models.DateField(_("Check date"), default=datetime.date.today)
estimated_value = models.FloatField(_("Estimated value"), blank=True, null=True)
collection = models.ForeignKey(
- "archaeological_warehouse.Warehouse",
+ "archaeological_warehouse.Warehouse", blank=True, null=True, on_delete=models.SET_NULL,
+ related_name="finds",
verbose_name=_("Collection"),
+ help_text=_("Do not use - need evolutions"),
+ )
+ # museum module
+ museum_owner_institution = models.ForeignKey(
+ Organization, blank=True, null=True, on_delete=models.SET_NULL,
+ related_name="owns",
+ verbose_name=_("Owner institution"),
+ )
+ museum_custodian_institution = models.ForeignKey(
+ Organization, blank=True, null=True, on_delete=models.SET_NULL,
+ related_name="deposited",
+ verbose_name=_("Custodian institution"),
+ )
+ museum_depositor_inventory_number = models.TextField(_("Depositor inventory number"), blank=True, default="")
+ museum_collection_entry_mode = models.ForeignKey(
+ CollectionEntryModeType, blank=True, null=True, on_delete=models.SET_NULL,
+ verbose_name=_("Collections entry mode"),
+ )
+ museum_entry_mode_comment = models.TextField(_("Comment on museum entry mode"), blank=True, default="")
+ museum_entry_date = models.DateField(_("Museum entry date (exact or start)"), blank=True, null=True)
+ museum_entry_date_end = models.DateField(_("Museum entry date (end)"), blank=True, null=True)
+ museum_entry_date_comment = models.TextField(_("Comment on museum entry date"), blank=True, default="")
+ museum_donor = models.ForeignKey(
+ BiographicalNote, blank=True, null=True, on_delete=models.SET_NULL,
+ related_name='has_provided',
+ verbose_name=_("Donor, testator or vendor"),
+ )
+ museum_inventory_marking_presence = models.ManyToManyField(
+ InventoryMarkingPresence, blank=True,
+ related_name="finds",
+ verbose_name=_("Presence of inventory marking"),
+ )
+ museum_marking_type = models.ManyToManyField(
+ MarkingType,
+ verbose_name=_("Type of marking"),
blank=True,
- null=True,
related_name="finds",
- on_delete=models.SET_NULL,
- help_text=_("Do not use - need evolutions"),
)
+ museum_marking_comment = models.TextField(_("Comment on marking"), blank=True, default="")
+ museum_collection = models.ForeignKey(
+ MuseumCollection, blank=True, null=True, on_delete=models.SET_NULL,
+ related_name='current_collection_of',
+ verbose_name=_("Collection"),
+ )
+ museum_former_collection = models.ForeignKey(
+ BiographicalNote, blank=True, null=True, on_delete=models.SET_NULL,
+ verbose_name=_("Former collection"),
+ )
+ museum_inventory_entry_year = models.PositiveIntegerField(
+ _("Inventory entry year"), blank=True, null=True
+ )
+ museum_inventory_conformity = models.ForeignKey(
+ InventoryConformity, blank=True, null=True, on_delete=models.SET_NULL,
+ verbose_name=_("Conformity with inventory"),
+ )
+ museum_non_conformity_comment = models.TextField(_("Comment of non-conformity"), blank=True, default="")
+ museum_inventory_transcript = models.TextField(_("Inventory transcript"), blank=True, default="")
+ museum_original_repro = models.ForeignKey(
+ OriginalReproduction, blank=True, null=True, on_delete=models.SET_NULL,
+ verbose_name=_("Original/reproduction"),
+ )
+ museum_allocation_date = models.DateField(_("Date of museum allocation"), blank=True, null=True)
+ museum_purchase_price = models.TextField(_("Purchase price"), blank=True, default="")
# preservation module
conservatory_state = models.ForeignKey(
@@ -1924,6 +2132,13 @@ class Find(
default="",
help_text=_("Generated automatically - do not edit"),
)
+ cache_complete_museum_id = models.TextField(
+ _("Complete museum ID"),
+ blank=True,
+ default="",
+ db_index=True,
+ help_text=_("Cached value - do not edit"),
+ )
history = HistoricalRecords(bases=[HistoryModel])
BASKET_MODEL = FindBasket
@@ -2585,6 +2800,12 @@ class Find(
return "-"
return self.base_finds.all()[0].cached_label
+ def complete_museum_id(self):
+ return self.cache_complete_museum_id
+
+ def _generate_cache_complete_museum_id(self):
+ return get_generated_id("find_complete_museum_id", self) or ""
+
def _generate_cached_periods(self):
return " & ".join([dating.period.label for dating in self.datings.all()])