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