summaryrefslogtreecommitdiff
path: root/archaeological_finds/models_finds.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_finds/models_finds.py')
-rw-r--r--archaeological_finds/models_finds.py306
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