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 |
