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)  | 
