diff options
Diffstat (limited to 'archaeological_finds/models_treatments.py')
-rw-r--r-- | archaeological_finds/models_treatments.py | 195 |
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) |