summaryrefslogtreecommitdiff
path: root/archaeological_finds/models_treatments.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_finds/models_treatments.py')
-rw-r--r--archaeological_finds/models_treatments.py195
1 files changed, 142 insertions, 53 deletions
diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py
index 168c87e2f..cbca04c9a 100644
--- a/archaeological_finds/models_treatments.py
+++ b/archaeological_finds/models_treatments.py
@@ -22,13 +22,14 @@ import datetime
from django.conf import settings
from django.contrib.gis.db import models
from django.contrib.postgres.indexes import GinIndex
+from django.db import transaction
from django.db.models import Max, Q
from django.db.models.signals import post_save, post_delete, pre_delete, m2m_changed
from django.template.defaultfilters import slugify
from django.urls import reverse
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy, SheetItem
-from archaeological_finds.models_finds import Find, FindBasket, TreatmentType
+from archaeological_finds.models_finds import Find, FindBasket, TreatmentType, FindTreatment
from archaeological_operations.models import ClosedItem, Operation
from archaeological_context_records.models import Dating
from archaeological_warehouse.models import Warehouse, Container
@@ -81,6 +82,14 @@ class TreatmentState(GeneralType):
return None
return q.all()[0].pk
+ @classmethod
+ def get_completed_state(cls):
+ treat_state, __ = cls.objects.get_or_create(
+ txt_idx='completed',
+ defaults={
+ 'label': _("Completed"), 'executed': True,
+ 'available': True})
+ return treat_state
post_save.connect(post_save_cache, sender=TreatmentState)
post_delete.connect(post_save_cache, sender=TreatmentState)
@@ -560,6 +569,50 @@ class Treatment(
for item in new_items:
b.items.add(item)
+ @property
+ def associated_filename(self):
+ return "-".join(
+ str(slugify(getattr(self, attr))) for attr in ("year", "index", "label")
+ )
+
+ def get_find_treatment_list(self):
+ return FindTreatment.objects.filter(treatment=self).all()
+
+ def clean_cache(self):
+ self._saved_container_attributes, self._is_loan_return, self._is_new_find_creator = None, None, None
+ self._is_current_container_changer, self._is_reference_container_changer = None, None
+
+ @property
+ def is_loan_return(self):
+ if getattr(self, "_is_loan_return", None) is None:
+ self._is_loan_return = any(
+ 1 for tp in self.treatment_types.all() if tp.restore_reference_location
+ )
+ return self._is_loan_return
+
+ @property
+ def is_new_find_creator(self):
+ if getattr(self, "_is_new_find_creator", None) is None:
+ self._is_new_find_creator = any(
+ 1 for tp in self.treatment_types.all() if tp.create_new_find
+ )
+ return self._is_new_find_creator
+
+ @property
+ def is_current_container_changer(self):
+ if getattr(self, "_is_current_container_changer", None) is None:
+ self._is_current_container_changer = self.treatment_types.filter(
+ change_current_location=True
+ ).exists()
+ return self._is_current_container_changer
+
+ @property
+ def is_reference_container_changer(self):
+ if getattr(self, "_is_reference_container_changer", None) is None:
+ self._is_reference_container_changer = self.treatment_types.filter(
+ change_reference_location=True).exists()
+ return self._is_reference_container_changer
+
def save(self, *args, **kwargs):
items, user, extra_args_for_new, resulting_find = [], None, [], None
upstream_items, upstream_item, resulting_finds = [], None, None
@@ -583,7 +636,9 @@ class Treatment(
if "return_new" in kwargs:
return_new = kwargs.pop("return_new")
self.pre_save()
- super(Treatment, self).save(*args, **kwargs)
+ super().save(*args, **kwargs)
+ # reinit cached values
+ self.clean_cache()
to_be_executed = not self.executed and self.treatment_state.executed
updated = []
@@ -620,7 +675,7 @@ class Treatment(
self.save()
return
- create_new_find = bool([tp for tp in treatment_types if tp.create_new_find])
+ create_new_find = self.is_new_find_creator
new_items = []
for item in items:
@@ -642,71 +697,105 @@ class Treatment(
basket.items.remove(item)
basket.items.add(new)
+ if to_be_executed or self.executed:
+ self.verify_find_container_history()
+
if not to_be_executed:
if return_new:
return new_items
return
- if create_new_find:
- q = Find.objects.filter(upstream_treatment=self)
- else:
- q = Find.objects.filter(treatments=self)
-
# manage loan return
- for tp in treatment_types:
- if tp.restore_reference_location:
- for find in q.all():
- if find.container_ref:
- find.container = find.container_ref
- if find.pk in updated:
- # don't record twice history
- find.skip_history_when_saving = True
- find.save()
- self.executed = True
- self.save()
- break
-
+ if self.loan_return(updated=updated):
+ self.executed = True
+ self.save()
# manage containers
- if not self.container:
- if return_new:
- return new_items
- return
+ elif self.container and self.move_finds_to_new_container(updated=updated):
+ self.executed = True
+ self.save()
+ if return_new:
+ return new_items
+ return
- container_attrs = []
- for tp in treatment_types:
- if tp.change_current_location:
- if "container" in container_attrs:
- continue
+ @property
+ def saved_container_attributes(self):
+ """
+ Return container attribute to change depending on treatment types
+ """
+ if getattr(self, "_saved_container_attributes", None) is None:
+ container_attrs = []
+ if self.is_current_container_changer:
container_attrs.append("container")
- if tp.change_reference_location:
- if "container_ref" in container_attrs:
- continue
+ if self.is_reference_container_changer:
container_attrs.append("container_ref")
+ self._saved_container_attributes = container_attrs
+ return self._saved_container_attributes
+
+ def verify_find_container_history(self):
+ container_attrs = self.saved_container_attributes
+ if (not self.container or not container_attrs) and not self.is_loan_return:
+ return False
+ q = self._get_finds_query_for_treatments()
+ if not q.exists():
+ return False
+ for find in q.all():
+ q2 = FindTreatment.objects.filter(find=find, treatment=self)
+ for find_treatment in q2.all():
+ find_treatment.generate_full_location()
+ def _get_finds_query_for_treatments(self):
+ if self.is_new_find_creator:
+ return Find.objects.filter(upstream_treatment=self)
+ return Find.objects.filter(treatments=self)
+
+ def loan_return(self, updated=None):
+ """
+ Manage loan return - change find location using treatment info
+ :param treatment_types: if not provided re-fetched from database
+ :param updated: list of already updated finds
+ :return: True if container changed
+ """
+ if not updated:
+ updated = []
+ if not self.is_loan_return:
+ return False
+ q = self._get_finds_query_for_treatments()
+ for find in q.all():
+ if find.container_ref and find.container != find.container_ref:
+ find.container = find.container_ref
+ if find.pk in updated:
+ # don't record twice history
+ find.skip_history_when_saving = True
+ else:
+ updated.append(find.pk)
+ find.save()
+ return True
+
+ def move_finds_to_new_container(self, container_attrs=None, updated=None):
+ """
+ Change find location using treatment info
+ :param updated: list of already updated finds
+ to update
+ :return: True if container changed
+ """
+ if not updated:
+ updated = []
if not container_attrs:
- # non consistent treatment
- if return_new:
- return new_items
- return
+ container_attrs = self.saved_container_attributes
+ if not container_attrs:
+ return False
+ q = self._get_finds_query_for_treatments()
for find in q.all():
for container_attr in container_attrs:
- if getattr(find, container_attr) != self.container:
- setattr(find, container_attr, self.container)
- if find.pk in updated:
- # don't record twice history
- find.skip_history_when_saving = True
- find.save()
- self.executed = True
- self.save()
- if return_new:
- return new_items
-
- @property
- def associated_filename(self):
- return "-".join(
- str(slugify(getattr(self, attr))) for attr in ("year", "index", "label")
- )
+ setattr(find, container_attr, self.container)
+ if find.pk in updated:
+ # don't record twice history
+ find.skip_history_when_saving = True
+ else:
+ updated.append(find.pk)
+ find.save()
+ return True
post_save.connect(cached_label_changed, sender=Treatment)