diff options
Diffstat (limited to 'archaeological_finds/models_finds.py')
| -rw-r--r-- | archaeological_finds/models_finds.py | 306 | 
1 files changed, 271 insertions, 35 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index e53ad6e6d..393583749 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -23,7 +23,7 @@ from django.conf import settings  from django.contrib.gis.db import models  from django.core.urlresolvers import reverse  from django.db import connection -from django.db.models import Max, Q +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 @@ -91,6 +91,11 @@ post_delete.connect(post_save_cache, sender=ConservatoryState)  class TreatmentType(HierarchicalType):      order = models.IntegerField(_(u"Order"), default=10)      virtual = models.BooleanField(_(u"Virtual")) +    destructive = models.BooleanField(_(u"Destructive"), default=False) +    create_new_find = models.BooleanField( +        _(u"Create a new find"), default=False, +        help_text=_(u"If True when this treatment is applied a new version " +                    u"of the object will be created."))      upstream_is_many = models.BooleanField(          _(u"Upstream is many"), default=False,          help_text=_( @@ -101,6 +106,16 @@ class TreatmentType(HierarchicalType):          help_text=_(              u"Check this if for this treatment from one find you'll get "              u"many.")) +    change_reference_location = models.BooleanField( +        _(u"Change reference location"), default=False, +        help_text=_(u"The treatment change the reference location.")) +    change_current_location = models.BooleanField( +        _(u"Change current location"), default=False, +        help_text=_(u"The treatment change the current location.")) +    restore_reference_location = models.BooleanField( +        _(u"Restore the reference location"), default=False, +        help_text=_(u"The treatment change restore reference location to the " +                    u"current location."))      class Meta:          verbose_name = _(u"Treatment type") @@ -326,6 +341,15 @@ class BaseFind(BulkUpdatedItem, BaseHistorizedItem, OwnPerms):          finds = self.find.filter().order_by("-order").all()          return finds and finds[0] +    def get_main_find(self): +        """ +        Get the last find which is not related to many base_find +        """ +        for find in self.find.order_by('-pk'): +            if find.base_finds.count() == 1: +                return find +        return +      def generate_index(self):          """          Generate index based on operation or context record (based on @@ -566,31 +590,54 @@ WEIGHT_UNIT = (('g', _(u"g")),                 ('kg', _(u"kg")),) -class FindBasket(Basket, OwnPerms): +class FindBasket(Basket, MainItem): +    SHOW_URL = 'show-findbasket'      items = models.ManyToManyField('Find', blank=True, related_name='basket') +    QUICK_ACTIONS = [ +        QuickAction( +            url="findbasket-qa-duplicate", icon_class="fa fa-clone", +            text=_(u"Duplicate"), target="one", +            rights=['view_find', 'view_own_find']), +    ] +      class Meta: +        verbose_name = _(u"Basket")          permissions = (              ("view_find", u"Can view all Finds"),              ("view_own_find", u"Can view own Find"),          ) -    @classmethod -    def get_query_owns(cls, ishtaruser): -        return Q(user=ishtaruser) -      def get_extra_actions(self, request):          """          For sheet template: return "Manage basket" action          """          # url, base_text, icon, extra_text, extra css class, is a quick action -        # no particular rights: if you can view an itm you can add it to your -        # own basket -        actions = [ -            (reverse("select_itemsinbasket", args=[self.pk]), -             _(u"Manage basket"), -             "fa fa-shopping-basket", "", "", False), +        if not request.user or not request.user.ishtaruser: +            return [] + +        ishtaruser = request.user.ishtaruser +        actions = [] +        if self.user == ishtaruser or ishtaruser.pk in [ +                user.pk for user in self.shared_write_with.all()]: +            actions = [ +                (reverse("select_itemsinbasket", args=[self.pk]), +                 _(u"Manage basket"), +                 "fa fa-shopping-basket", "", "", False), +            ] +        can_edit_find = self.can_do(request, 'change_find') +        if can_edit_find: +            actions += [ +                (reverse('findbasket-add-treatment', args=[self.pk]), +                 _(u"Add treatment"), "fa fa-exchange", "", "", False), +            ] + +        duplicate = self.QUICK_ACTIONS[0] +        actions += [ +            (reverse(duplicate.url, args=[self.pk]), +             duplicate.text, duplicate.icon_class, +             "", "", True),          ]          return actions @@ -631,6 +678,20 @@ class FBulkView(object):      """ +def query_loan(is_true=True): +    """ +    Query to get loan find + +    :return: (filter, exclude, extra) +    """ +    if is_true: +        return Q(container_ref__isnull=False, container__isnull=False), \ +               Q(container_ref=F('container')), None +    else: +        return Q(container_ref__isnull=False, container__isnull=False, +                 container_ref=F('container')), None, None + +  class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,             MainItem):      EXTERNAL_ID_KEY = 'find_external_id' @@ -642,7 +703,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,                    'base_finds__context_record__label',                    'material_types__label', 'object_types__label',                    'datings__period__label', -                  'container__cached_label', ] +                  'container__cached_label', +                  'container_ref__cached_label']      if settings.COUNTRY == 'fr':          TABLE_COLS.insert(              3, 'base_finds__context_record__operation__code_patriarche') @@ -652,7 +714,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          'previous_id', 'label', 'material_types__label',          'datings__period__label', 'find_number', 'object_types__label',          'container__cached_label', -        'container__cached_location', +        'container_ref__cached_label',          'description',          'base_finds__context_record__town__name',          'base_finds__context_record__parcel', ] @@ -670,7 +732,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          'base_finds__context_record__archaeological_site__name':              IshtarSiteProfile.get_default_site_label,          'base_finds__context_record__parcel': _(u"Parcel"), -        'base_finds__batch':_(u"Batch"), +        'base_finds__batch': _(u"Batch"),          'base_finds__comment': _(u"Base find - Comment"),          'base_finds__description': _(u"Base find - Description"),          'base_finds__topographic_localisation': _(u"Base find - " @@ -680,7 +742,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              u"Base find - Discovery date (exact or TPQ)"),          'base_finds__discovery_date_taq': _(              u"Base find - Discovery date (TAQ)"), -        'container__cached_label': _(u"Container"), +        'container__cached_label': _(u"Current container"), +        'container_ref__cached_label': _(u"Reference container"),          'datings__period__label': _(u"Periods"),          'material_types__label': _(u"Material types"),          'object_types__label': _(u"Object types"), @@ -706,7 +769,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              'base_finds__context_record__',      } -    DATED_FIELDS = ['last_modified__gte'] +    DATED_FIELDS = ['last_modified__gte', 'treatments__file__end_date__lte']      BASE_REQUEST = {'downstream_treatment__isnull': True}      EXTRA_REQUEST_KEYS = {          'base_finds__context_record': @@ -863,20 +926,36 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              pgettext_lazy("key for text search", u"has-image"),              'documents__image__isnull',          ), -        'container__location': ( +        'container_ref__location': (              pgettext_lazy("key for text search", u"location"), +            'container_ref__location__name__iexact', +        ), +        'container_ref__responsible': ( +            pgettext_lazy("key for text search", u"warehouse"), +            'container_ref__responsible__name__iexact', +        ), +        'container_ref__index': ( +            pgettext_lazy("key for text search", u"container-index"), +            'container_ref__index', +        ), +        'container_ref__reference': ( +            pgettext_lazy("key for text search", u"container-ref"), +            'container_ref__reference__iexact', +        ), +        'container__location': ( +            pgettext_lazy("key for text search", u"current-location"),              'container__location__name__iexact',          ),          'container__responsible': ( -            pgettext_lazy("key for text search", u"warehouse"), +            pgettext_lazy("key for text search", u"current-warehouse"),              'container__responsible__name__iexact',          ),          'container__index': ( -            pgettext_lazy("key for text search", u"container-index"), +            pgettext_lazy("key for text search", u"current-container-index"),              'container__index',          ),          'container__reference': ( -            pgettext_lazy("key for text search", u"container-ref"), +            pgettext_lazy("key for text search", u"current-container-ref"),              'container__reference__iexact',          ),          'basket': ( @@ -899,6 +978,14 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              pgettext_lazy("key for text search", u"created-by"),              'history_creator__ishtaruser__person__cached_label__iexact'          ), +        'loan': ( +            pgettext_lazy("key for text search", u"loan"), +            query_loan +        ), +        'treatments_file_end_date': ( +            pgettext_lazy("key for text search", u"treatment-end-date-before"), +            'treatments__file__end_date__lte' +        )      }      for v in ALT_NAMES.values():          for language_code, language_lbl in settings.LANGUAGES: @@ -906,6 +993,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1]              deactivate() +    EXTRA_REQUEST_FUNC = {""} +      PARENT_SEARCH_VECTORS = ['base_finds']      BASE_SEARCH_VECTORS = [          "cached_label", "label", "description", "container__location__name", @@ -1003,6 +1092,11 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          "archaeological_warehouse.Container", verbose_name=_(u"Container"),          blank=True, null=True,          related_name='finds', on_delete=models.SET_NULL) +    container_ref = models.ForeignKey( +        "archaeological_warehouse.Container", +        verbose_name=_(u"Reference container"), +        blank=True, null=True, +        related_name='finds_ref', on_delete=models.SET_NULL)      is_complete = models.NullBooleanField(_(u"Is complete?"), blank=True,                                            null=True)      object_types = models.ManyToManyField( @@ -1029,6 +1123,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,      width = models.FloatField(_(u"Width (cm)"), blank=True, null=True)      height = models.FloatField(_(u"Height (cm)"), blank=True, null=True)      diameter = models.FloatField(_(u"Diameter (cm)"), blank=True, null=True) +    circumference = models.FloatField(_(u"Circumference (cm)"), blank=True, +                                      null=True)      thickness = models.FloatField(_(u"Thickness (cm)"), blank=True, null=True)      clutter_long_side = models.FloatField(          _(u"Clutter - long side (cm)"), blank=True, null=True) @@ -1083,6 +1179,10 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,      documents = models.ManyToManyField(          Document, related_name='finds', verbose_name=_(u"Documents"),          blank=True) +    treatments = models.ManyToManyField( +        "Treatment", verbose_name=_(u"Treatments"), +        related_name='finds', blank=True, +        help_text=_(u"Related treatments when no new find is created"))      cached_label = models.TextField(_(u"Cached name"), null=True, blank=True,                                      db_index=True)      history = HistoricalRecords() @@ -1156,6 +1256,22 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              return          return self.base_finds.order_by('-pk').all()[0] +    def get_values(self, prefix=''): +        values = super(Find, self).get_values(prefix=prefix) +        return values +        # TODO +        bf = self.get_first_base_find() +        if not bf: +            return values +        operation = bf.context_record.operation +        values[prefix + "operation"] = [ +            { +                "common_name": operation.common_name, +                "code_patriarche": operation.code_patriarche, +                "address": operation.address +            } +        ] +      @property      def reference(self):          bf = self.get_first_base_find() @@ -1179,6 +1295,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,                  (reverse("find-qa-basket", args=[self.pk]),                   _(u"Add to basket"),                   "fa fa-shopping-basket", "", "", True), +                (reverse('find-add-treatment', args=[self.pk]), +                 _(u"Add treatment"), "fa fa-exchange", "", "", False),              ]              if get_current_profile().warehouse:                  actions.append( @@ -1338,7 +1456,7 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              q = q.filter(**fltr)          return q.filter(downstream_treatment__isnull=True).count() -    def duplicate(self, user): +    def duplicate(self, user, copy_datings=True):          model = self.__class__          new = model.objects.get(pk=self.pk) @@ -1356,12 +1474,22 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          m2m = [field.name for field in model._meta.many_to_many                 if field.name not in PRIVATE_FIELDS]          for field in m2m: -            if field == 'images': -                for doc in Document.objects.filter(finds__pk=self.pk).all(): -                    doc.finds.add(new.pk) +            if field == 'datings' and copy_datings: +                for dating in self.datings.all(): +                    is_present = False +                    for current_dating in new.datings.all(): +                        if Dating.is_identical(current_dating, dating): +                            is_present = True +                            break +                    if is_present: +                        continue +                    dating.pk = None +                    dating.save() +                    new.datings.add(dating)              else:                  for val in getattr(self, field).all(): -                    getattr(new, field).add(val) +                    if val not in getattr(new, field).all(): +                        getattr(new, field).add(val)          return new      @classmethod @@ -1375,6 +1503,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          ) | cls._construct_query_own(              'base_finds__context_record__operation__',              Operation._get_query_owns_dicts(ishtaruser) +        ) | cls._construct_query_own( +            'basket__', +            [{"shared_with": ishtaruser, "shared_write_with": ishtaruser}]          ) | cls._construct_query_own('', [              {'history_creator': ishtaruser.user_ptr},              {'base_finds__context_record__operation__end_date__isnull': True} @@ -1493,21 +1624,62 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          with connection.cursor() as c:              c.execute(sql, args) -    def get_localisation(self, place): +    def get_localisation(self, place, is_ref=False):          """          Get localisation reference in the warehouse          :param place: number of the localisation starting with 0 +        :param is_ref: if true - reference container else current container          :return: reference - empty string if not available          """ -        if not self.container: +        if is_ref: +            container = self.container_ref +        else: +            container = self.container +        if not container:              return "" -        locas = self.container.get_localisations() +        locas = container.get_localisations()          if len(locas) < (place + 1):              return ""          return locas[place]      @property +    def reference_localisation_1(self): +        return self.get_localisation(0, is_ref=True) + +    @property +    def reference_localisation_2(self): +        return self.get_localisation(1, is_ref=True) + +    @property +    def reference_localisation_3(self): +        return self.get_localisation(2, is_ref=True) + +    @property +    def reference_localisation_4(self): +        return self.get_localisation(3, is_ref=True) + +    @property +    def reference_localisation_5(self): +        return self.get_localisation(4, is_ref=True) + +    @property +    def reference_localisation_6(self): +        return self.get_localisation(5, is_ref=True) + +    @property +    def reference_localisation_7(self): +        return self.get_localisation(6, is_ref=True) + +    @property +    def reference_localisation_8(self): +        return self.get_localisation(7, is_ref=True) + +    @property +    def reference_localisation_9(self): +        return self.get_localisation(8, is_ref=True) + +    @property      def localisation_1(self):          return self.get_localisation(0) @@ -1543,19 +1715,75 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,      def localisation_9(self):          return self.get_localisation(8) -    def set_localisation(self, place, context, value): -        if not self.container: +    def set_localisation(self, place, context, value, is_ref=False): +        """ +        Get localisation reference in the warehouse + +        :param place: number of the localisation starting with 0 +        :param context: context of the request - not used +        :param value: localisation value +        :param is_ref: if true - reference container else current container +        :return: None +        """ +        if is_ref: +            container = self.container_ref +        else: +            container = self.container + +        if not container:              if not value:                  return -            raise ImporterError(_(u"No container have been set - the " -                                  u"localisation cannot be set.")) +            if is_ref: +                raise ImporterError( +                    _(u"No reference container have been set - the " +                      u"localisation cannot be set.")) +            else: +                raise ImporterError( +                    _(u"No container have been set - the localisation cannot " +                      u"be set.")) -        localisation = self.container.set_localisation(place, value) +        localisation = container.set_localisation(place, value)          if value and value != '-' and not localisation:              raise ImporterError(                  unicode(_(u"The division number {} have not been set "                            u"for the warehouse {}.")).format( -                    place + 1, self.container.location)) +                    place + 1, container.location)) + +    @post_importer_action +    def set_reference_localisation_1(self, context, value): +        return self.set_localisation(0, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_2(self, context, value): +        return self.set_localisation(1, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_3(self, context, value): +        return self.set_localisation(2, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_4(self, context, value): +        return self.set_localisation(3, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_5(self, context, value): +        return self.set_localisation(4, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_6(self, context, value): +        return self.set_localisation(5, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_7(self, context, value): +        return self.set_localisation(6, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_8(self, context, value): +        return self.set_localisation(7, context, value, is_ref=True) + +    @post_importer_action +    def set_reference_localisation_9(self, context, value): +        return self.set_localisation(8, context, value, is_ref=True)      @post_importer_action      def set_localisation_1(self, context, value): @@ -1634,6 +1862,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          super(Find, self).save(*args, **kwargs)          self.skip_history_when_saving = True +        if self.container_ref and not self.container: +            self.container = self.container_ref +          updated = self.update_external_id(save=False)          if updated:              self._cached_label_checked = False @@ -1649,6 +1880,9 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,          for base_find in self.base_finds.filter(                  context_record__operation__pk__isnull=False).all():              modified = False +            if self.label and not base_find.label: +                base_find.label = self.label +                modified = True              if not base_find.index:                  modified = base_find.generate_index()              short_id = base_find.short_id() @@ -1659,6 +1893,8 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms,              if base_find.cache_complete_id != complete_id:                  base_find.cache_complete_id = complete_id                  modified = True +            if base_find.update_external_id(): +                modified = True              if modified:                  base_find.skip_history_when_saving = True                  base_find._cached_label_checked = False  | 
