diff options
Diffstat (limited to 'archaeological_finds/models_finds.py')
-rw-r--r-- | archaeological_finds/models_finds.py | 273 |
1 files changed, 182 insertions, 91 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 66059079b..811e6be74 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -28,17 +28,19 @@ from django.db.models.signals import m2m_changed, post_save, post_delete, \ pre_delete from django.utils.translation import ugettext_lazy as _, ugettext +from ishtar_common.data_importer import post_importer_action, ImporterError from ishtar_common.utils import cached_label_changed, post_save_point from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \ ShortMenuItem, LightHistorizedItem, HistoricalRecords, OwnPerms, Source, \ - Person, Basket, get_external_id, post_save_cache, ValueGetter, \ + Person, Basket, post_save_cache, ValueGetter, \ get_current_profile from archaeological_operations.models import AdministrativeAct from archaeological_context_records.models import ContextRecord, Dating -from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem +from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem, \ + BulkUpdatedItem class MaterialType(GeneralType): @@ -148,7 +150,9 @@ class BFBulkView(object): """ -class BaseFind(BaseHistorizedItem, OwnPerms): +class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms): + EXTERNAL_ID_KEY = 'base_find_external_id' + EXTERNAL_ID_DEPENDENCIES = ['find'] label = models.TextField(_(u"Free ID")) external_id = models.TextField(_(u"External ID"), blank=True, null=True) auto_external_id = models.BooleanField( @@ -182,7 +186,7 @@ class BaseFind(BaseHistorizedItem, OwnPerms): SpatialReferenceSystem, verbose_name=_(u"Spatial Reference System"), blank=True, null=True) point_2d = models.PointField(_(u"Point (2D)"), blank=True, null=True) - point = models.PointField(_(u"Point"), blank=True, null=True, dim=3) + point = models.PointField(_(u"Point (3D)"), blank=True, null=True, dim=3) line = models.LineStringField(_(u"Line"), blank=True, null=True) polygon = models.PolygonField(_(u"Polygon"), blank=True, null=True) cache_short_id = models.TextField( @@ -199,11 +203,11 @@ class BaseFind(BaseHistorizedItem, OwnPerms): verbose_name = _(u"Base find") verbose_name_plural = _(u"Base finds") permissions = ( - ("view_basefind", ugettext(u"Can view all Base finds")), - ("view_own_basefind", ugettext(u"Can view own Base find")), - ("add_own_basefind", ugettext(u"Can add own Base find")), - ("change_own_basefind", ugettext(u"Can change own Base find")), - ("delete_own_basefind", ugettext(u"Can delete own Base find")), + ("view_basefind", u"Can view all Base finds"), + ("view_own_basefind", u"Can view own Base find"), + ("add_own_basefind", u"Can add own Base find"), + ("change_own_basefind", u"Can change own Base find"), + ("delete_own_basefind", u"Can delete own Base find"), ) def __unicode__(self): @@ -224,12 +228,12 @@ class BaseFind(BaseHistorizedItem, OwnPerms): profile = get_current_profile() if profile.find_index == u'O': operation = self.context_record.operation - q = Find.objects \ - .filter(base_finds__context_record__operation=operation) + q = BaseFind.objects \ + .filter(context_record__operation=operation) elif profile.find_index == u'CR': cr = self.context_record - q = Find.objects \ - .filter(base_finds__context_record=cr) + q = BaseFind.objects \ + .filter(context_record=cr) else: return False if self.pk: @@ -326,31 +330,13 @@ class BaseFind(BaseHistorizedItem, OwnPerms): return self.label @classmethod - def get_extra_fields(cls): - fields = {} - for field in Find._meta.many_to_many: - if field.name == 'base_finds': - fields['find'] = field.related.model - return fields - - def save(self, *args, **kwargs): - returned = super(BaseFind, self).save(*args, **kwargs) - - updated = False - if not self.external_id or self.auto_external_id: - external_id = get_external_id('base_find_external_id', self) - if external_id != self.external_id: - updated = True - self.auto_external_id = True - self.external_id = external_id - if updated: - self._cached_label_checked = False - self.save() - return returned - - @classmethod def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, - context_record_id=None): + context_record_id=None, transaction_id=None): + transaction_id, is_recursion = cls.bulk_recursion( + transaction_id, [operation_id, parcel_id, context_record_id]) + if is_recursion: + return + if operation_id: filters = """ INNER JOIN archaeological_context_records_contextrecord acr @@ -373,6 +359,7 @@ class BaseFind(BaseHistorizedItem, OwnPerms): kwargs = {'context_record_id': context_record_id} else: return + kwargs['transaction_id'] = transaction_id sql = """ UPDATE "archaeological_finds_basefind" AS bf @@ -450,12 +437,9 @@ class BaseFind(BaseHistorizedItem, OwnPerms): ope_prefix=settings.ISHTAR_DEF_OPE_PREFIX, join=settings.JOINT, filters=filters, zeros=settings.ISHTAR_FINDS_INDEX_ZERO_LEN * "0") - # with connection.cursor() as c: # django 1.8 - c = connection.cursor() - c.execute(sql, args) - transaction.commit_unless_managed() - cls._meta.get_field_by_name( - 'find')[0].model.cached_label_bulk_update(**kwargs) + with connection.cursor() as c: + c.execute(sql, args) + Find.cached_label_bulk_update(**kwargs) post_save.connect(post_save_point, sender=BaseFind) @@ -470,8 +454,7 @@ CHECK_CHOICES = (('NC', _(u"Not checked")), class FindBasket(Basket): - items = models.ManyToManyField('Find', blank=True, null=True, - related_name='basket') + items = models.ManyToManyField('Find', blank=True, related_name='basket') class FirstBaseFindView(object): @@ -510,8 +493,9 @@ class FBulkView(object): """ -class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, - ShortMenuItem): +class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, ImageModel, + OwnPerms, ShortMenuItem): + EXTERNAL_ID_KEY = 'find_external_id' CHECK_DICT = dict(CHECK_CHOICES) SHOW_URL = 'show-find' SLUG = 'find' @@ -519,7 +503,7 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, 'base_finds__context_record__operation__common_name', 'base_finds__context_record__parcel', 'base_finds__context_record__label', - 'material_types__label', 'object_types', + 'material_types__label', 'object_types__label', 'datings__period__label', 'container__cached_label', 'base_finds__batch', ] @@ -530,7 +514,7 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, 'base_finds__cache_short_id', 'base_finds__cache_complete_id', 'previous_id', 'label', 'material_types__label', - 'datings__period__label', 'find_number', 'object_types', + 'datings__period__label', 'find_number', 'object_types__label', 'container__cached_label', 'description', 'base_finds__context_record__parcel__town', @@ -557,6 +541,7 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, 'container__cached_label': _(u"Container"), 'datings__period__label': _(u"Periods"), 'material_types__label': _(u"Material types"), + 'object_types__label': _(u"Object types"), } EXTRA_FULL_FIELDS = [ @@ -636,7 +621,9 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, label = models.TextField(_(u"Free ID")) description = models.TextField(_(u"Description"), blank=True, null=True) material_types = models.ManyToManyField( - MaterialType, verbose_name=_(u"Material types"), related_name='finds') + MaterialType, verbose_name=_(u"Material types"), related_name='finds', + blank=True + ) conservatory_state = models.ForeignKey( ConservatoryState, verbose_name=_(u"Conservatory state"), blank=True, null=True, on_delete=models.SET_NULL) @@ -644,7 +631,7 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, blank=True, null=True) preservation_to_considers = models.ManyToManyField( PreservationType, verbose_name=_(u"Type of preservation to consider"), - related_name='finds') + related_name='finds', blank=True) volume = models.FloatField(_(u"Volume (l)"), blank=True, null=True) weight = models.FloatField(_(u"Weight (g)"), blank=True, null=True) weight_unit = models.CharField(_(u"Weight unit"), max_length=4, @@ -666,13 +653,15 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, is_complete = models.NullBooleanField(_(u"Is complete?"), blank=True, null=True) object_types = models.ManyToManyField( - ObjectType, verbose_name=_(u"Object types"), related_name='find') + ObjectType, verbose_name=_(u"Object types"), related_name='find', + blank=True + ) integrities = models.ManyToManyField( IntegrityType, verbose_name=_(u"Integrity / interest"), - related_name='find') + related_name='find', blank=True) remarkabilities = models.ManyToManyField( RemarkabilityType, verbose_name=_(u"Remarkability"), - related_name='find') + related_name='find', blank=True) min_number_of_individuals = models.IntegerField( _(u"Minimum number of individuals (MNI)"), blank=True, null=True) length = models.FloatField(_(u"Length (cm)"), blank=True, null=True) @@ -688,7 +677,7 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, null=True) previous_id = models.TextField(_(u"Previous ID"), blank=True, null=True) index = models.IntegerField(u"Index", default=0) - checked = models.CharField(_(u"Check"), max_length=2, default='NC', + checked = models.CharField(_(u"Check"), max_length=2, default=u'NC', choices=CHECK_CHOICES) check_date = models.DateField(_(u"Check date"), default=datetime.date.today) @@ -700,17 +689,16 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, cached_label = models.TextField(_(u"Cached name"), null=True, blank=True) history = HistoricalRecords() BASKET_MODEL = FindBasket - IMAGE_PREFIX = 'finds/' class Meta: verbose_name = _(u"Find") verbose_name_plural = _(u"Finds") permissions = ( - ("view_find", ugettext(u"Can view all Finds")), - ("view_own_find", ugettext(u"Can view own Find")), - ("add_own_find", ugettext(u"Can add own Find")), - ("change_own_find", ugettext(u"Can change own Find")), - ("delete_own_find", ugettext(u"Can delete own Find")), + ("view_find", u"Can view all Finds"), + ("view_own_find", u"Can view own Find"), + ("add_own_find", u"Can add own Find"), + ("change_own_find", u"Can change own Find"), + ("delete_own_find", u"Can delete own Find"), ) ordering = ('cached_label',) @@ -733,6 +721,11 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, return u" ; ".join([unicode(dating) for dating in self.datings.all()]) @property + def materials(self): + return u" ; ".join([unicode(material) + for material in self.material_types.all()]) + + @property def show_url(self): return reverse('show-find', args=[self.pk, '']) @@ -753,10 +746,9 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, return lbl def get_first_base_find(self): - q = self.base_finds - if not q.count(): + if not self.base_finds.count(): return - return q.order_by('-pk').all()[0] + return self.base_finds.order_by('-pk').all()[0] @property def reference(self): @@ -765,15 +757,43 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, return "00" return bf.short_id() + def _get_base_image_path(self): + bf = None + if self.id: + bf = self.get_first_base_find() + if not bf: + return u"detached/{}".format(self.SLUG) + ope = bf.context_record.operation + find_idx = u'{:0' + str(settings.ISHTAR_FINDS_INDEX_ZERO_LEN) + 'd}' + return (u"operation/{}/{}/{}/" + find_idx).format( + ope.year, ope.reference, self.SLUG, self.index) + @property def administrative_index(self): bf = self.get_first_base_find() if not bf or not bf.context_record or not bf.context_record.operation: return "" - return "{}-{}".format( + return u"{}-{}".format( bf.context_record.operation.get_reference(), self.index) + def context_records_lbl(self): + return u" - ".join( + [bf.context_record.cached_label for bf in self.base_finds.all()] + ) + context_records_lbl.short_description = _(u"Context record") + context_records_lbl.admin_order_field = \ + "base_finds__context_record__cached_label" + + def operations_lbl(self): + return u" - ".join( + [bf.context_record.operation.cached_label + for bf in self.base_finds.all()] + ) + operations_lbl.short_description = _(u"Operation") + operations_lbl.admin_order_field = \ + "base_finds__context_record__operation__cached_label" + def _get_treatments(self, model, rel='upstream', limit=None): treatments, findtreats = [], [] q = model.objects.filter( @@ -909,14 +929,14 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, return new @classmethod - def get_query_owns(cls, user): - return (Q(base_finds__context_record__operation__scientist=user. + def get_query_owns(cls, ishtaruser): + return (Q(base_finds__context_record__operation__scientist= ishtaruser.person) | - Q(base_finds__context_record__operation__in_charge=user. + Q(base_finds__context_record__operation__in_charge= ishtaruser.person) | - Q(base_finds__context_record__operation__collaborators__pk=user. + Q(base_finds__context_record__operation__collaborators__pk= ishtaruser.person.pk) | - Q(history_creator=user)) \ + Q(history_creator=ishtaruser.user_ptr)) \ & Q(base_finds__context_record__operation__end_date__isnull=True) @classmethod @@ -937,7 +957,12 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, @classmethod def cached_label_bulk_update(cls, operation_id=None, parcel_id=None, - context_record_id=None): + context_record_id=None, transaction_id=None): + transaction_id, is_recursion = cls.bulk_recursion( + transaction_id, [operation_id, parcel_id, context_record_id]) + if is_recursion: + return + if operation_id: filters = """ INNER JOIN find_first_base_find myfbf @@ -1007,10 +1032,82 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, ope_prefix=settings.ISHTAR_DEF_OPE_PREFIX, join=settings.JOINT, filters=filters, zeros=settings.ISHTAR_FINDS_INDEX_ZERO_LEN * "0") - # with connection.cursor() as c: # django 1.8 - c = connection.cursor() - c.execute(sql, args) - transaction.commit_unless_managed() + with connection.cursor() as c: + c.execute(sql, args) + + def get_localisation(self, place): + """ + Get localisation reference in the warehouse + + :param place: number of the localisation starting with 0 + :return: reference - empty string if not available + """ + if not self.container: + return "" + locas = self.container.get_localisations() + if len(locas) < (place + 1): + return "" + return locas[place] + + @property + def localisation_1(self): + return self.get_localisation(0) + + @property + def localisation_2(self): + return self.get_localisation(1) + + @property + def localisation_3(self): + return self.get_localisation(2) + + @property + def localisation_4(self): + return self.get_localisation(3) + + @property + def localisation_5(self): + return self.get_localisation(4) + + @property + def localisation_6(self): + return self.get_localisation(5) + + def set_localisation(self, place, context, value): + if not self.container: + raise ImporterError(_(u"No container have been set - the " + u"localisation cannot be set.")) + + localisation = self.container.set_localisation(place, value) + if not localisation: + raise ImporterError( + unicode(_(u"The division number {} have not been set " + u"for the warehouse {}.")).format( + place + 1, self.container.location)) + + @post_importer_action + def set_localisation_1(self, context, value): + return self.set_localisation(0, context, value) + + @post_importer_action + def set_localisation_2(self, context, value): + return self.set_localisation(1, context, value) + + @post_importer_action + def set_localisation_3(self, context, value): + return self.set_localisation(2, context, value) + + @post_importer_action + def set_localisation_4(self, context, value): + return self.set_localisation(3, context, value) + + @post_importer_action + def set_localisation_5(self, context, value): + return self.set_localisation(4, context, value) + + @post_importer_action + def set_localisation_6(self, context, value): + return self.set_localisation(5, context, value) def generate_index(self): """ @@ -1052,14 +1149,8 @@ class Find(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, def save(self, *args, **kwargs): super(Find, self).save(*args, **kwargs) - updated = False self.skip_history_when_saving = True - if not self.external_id or self.auto_external_id: - external_id = get_external_id('find_external_id', self) - if external_id != self.external_id: - updated = True - self.auto_external_id = True - self.external_id = external_id + updated = self.update_external_id(save=False) if updated: self._cached_label_checked = False self.save() @@ -1175,15 +1266,15 @@ class FindSource(Source): verbose_name_plural = _(u"Find documentations") permissions = ( ("view_findsource", - ugettext(u"Can view all Find sources")), + u"Can view all Find sources"), ("view_own_findsource", - ugettext(u"Can view own Find source")), + u"Can view own Find source"), ("add_own_findsource", - ugettext(u"Can add own Find source")), + u"Can add own Find source"), ("change_own_findsource", - ugettext(u"Can change own Find source")), + u"Can change own Find source"), ("delete_own_findsource", - ugettext(u"Can delete own Find source")), + u"Can delete own Find source"), ) find = models.ForeignKey(Find, verbose_name=_(u"Find"), related_name="source") @@ -1193,13 +1284,13 @@ class FindSource(Source): return self.find @classmethod - def get_query_owns(cls, user): - return (Q(find__base_finds__context_record__operation__scientist=user. + def get_query_owns(cls, ishtaruser): + return (Q(find__base_finds__context_record__operation__scientist= ishtaruser.person) | - Q(find__base_finds__context_record__operation__in_charge=user. + Q(find__base_finds__context_record__operation__in_charge= ishtaruser.person) | Q( - find__base_finds__context_record__operation__collaborators__pk=user. + find__base_finds__context_record__operation__collaborators__pk= ishtaruser.person.pk)) \ & Q( find__base_finds__context_record__operation__end_date__isnull=True) |