summaryrefslogtreecommitdiff
path: root/archaeological_operations/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_operations/models.py')
-rw-r--r--archaeological_operations/models.py198
1 files changed, 196 insertions, 2 deletions
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 2db101104..ccafe5202 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -22,17 +22,18 @@ from itertools import groupby
from django.conf import settings
from django.contrib.gis.db import models
+from django.core.cache import cache
from django.core.urlresolvers import reverse
from django.db.models import Q, Count, Sum, Max, Avg
from django.db.models.signals import post_save, m2m_changed, post_delete
from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _, ugettext
-from ishtar_common.utils import cached_label_changed
+from ishtar_common.utils import cached_label_changed, get_cache, mode
from ishtar_common.models import GeneralType, BaseHistorizedItem, \
HistoricalRecords, LightHistorizedItem, OwnPerms, Department, Source,\
- Person, Organization, Town, Dashboard, IshtarUser, ValueGetter, \
+ SourceType, Person, Organization, Town, Dashboard, IshtarUser, ValueGetter,\
DocumentTemplate, ShortMenuItem, DashboardFormItem, GeneralRelationType,\
GeneralRecordRelations, post_delete_record_relation, OperationType, \
get_external_id
@@ -459,6 +460,199 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter,
self.operation_code = self.get_available_operation_code(self.year)
return super(Operation, self).save(*args, **kwargs)
+ @property
+ def nb_parcels(self):
+ nb = 0
+ if self.associated_file:
+ nb = self.associated_file.parcels.count()
+ if not nb:
+ nb = self.parcels.count()
+ return nb
+
+ def _get_or_set_stats(self, funcname, update):
+ key, val = get_cache(self.__class__, [funcname, self.pk])
+ if not update and val is not None:
+ return val
+ val = getattr(self, funcname)()
+ cache.set(key, val, settings.CACHE_TIMEOUT)
+ return val
+
+ @property
+ def nb_acts(self, update=False):
+ _(u"Number of administrative acts")
+ return self._get_or_set_stats('_nb_acts', update)
+
+ def _nb_acts(self):
+ return self.administrative_act.count()
+
+ @property
+ def nb_indexed_acts(self, update=False):
+ _(u"Number of indexed administrative acts")
+ return self._get_or_set_stats('_nb_indexed_acts', update)
+
+ def _nb_indexed_acts(self):
+ return self.administrative_act.filter(act_type__indexed=True).count()
+
+ @property
+ def nb_context_records(self, update=False):
+ _(u"Number of context records")
+ return self._get_or_set_stats('_nb_context_records', update)
+
+ def _nb_context_records(self):
+ return self.context_record.count()
+
+ @property
+ def nb_context_records_by_type(self, update=False):
+ return self._get_or_set_stats('_nb_context_records_by_type', update)
+
+ def _nb_context_records_by_type(self):
+ nbs = []
+ q = self.context_record.values(
+ 'unit', 'unit__label').distinct().order_by('label')
+ for res in q.all():
+ nbs.append((unicode(res['unit__label']),
+ self.context_record.filter(unit=res['unit']).count()))
+ return nbs
+
+ @property
+ def nb_context_records_by_periods(self, update=False):
+ return self._get_or_set_stats('_nb_context_records_by_periods', update)
+
+ def _nb_context_records_by_periods(self):
+ nbs = []
+ q = self.context_record.values(
+ 'datings__period', 'datings__period__label').distinct().order_by(
+ 'datings__period__order')
+ for res in q.all():
+ nbs.append((unicode(res['datings__period__label']),
+ self.context_record.filter(
+ datings__period=res['datings__period']).count()))
+ return nbs
+
+ @property
+ def nb_finds(self, update=False):
+ _(u"Number of finds")
+ return self._get_or_set_stats('_nb_finds', update)
+
+ def _nb_finds(self):
+ from archaeological_finds.models import Find
+ q = Find.objects.filter(
+ base_finds__context_record__operation=self)
+ return q.count()
+
+ @property
+ def nb_finds_by_material_type(self, update=False):
+ return self._get_or_set_stats('_nb_finds_by_material_type', update)
+
+ def _nb_finds_by_material_type(self):
+ from archaeological_finds.models import Find
+ nbs = []
+ q = Find.objects.filter(
+ base_finds__context_record__operation=self).values(
+ 'material_types__pk', 'material_types__label').distinct().order_by(
+ 'material_types__label')
+ for res in q.all():
+ nbs.append(
+ (unicode(res['material_types__label']),
+ Find.objects.filter(
+ material_types__pk=res['material_types__pk']).count()))
+ return nbs
+
+ @property
+ def nb_finds_by_types(self, update=False):
+ return self._get_or_set_stats('_nb_finds_by_types', update)
+
+ def _nb_finds_by_types(self):
+ from archaeological_finds.models import Find
+ nbs = []
+ q = Find.objects.filter(
+ base_finds__context_record__operation=self).values(
+ 'object_types', 'object_types__label').distinct().order_by(
+ 'object_types__label')
+ for res in q.all():
+ label = unicode(res['object_types__label'])
+ if label == 'None':
+ label = _(u"No type")
+ nbs.append(
+ (label,
+ Find.objects.filter(
+ object_types=res['object_types']).count()))
+ return nbs
+
+ @property
+ def nb_finds_by_periods(self, update=False):
+ return self._get_or_set_stats('_nb_finds_by_periods', update)
+
+ def _nb_finds_by_periods(self):
+ from archaeological_finds.models import Find
+ nbs = []
+ q = Find.objects.filter(
+ base_finds__context_record__operation=self).values(
+ 'datings__period', 'datings__period__label').distinct().order_by(
+ 'datings__period__order')
+ for res in q.all():
+ nbs.append(
+ (unicode(res['datings__period__label']),
+ Find.objects.filter(
+ datings__period=res['datings__period']).count()))
+ return nbs
+
+ @property
+ def nb_documents(self, update=False):
+ _(u"Number of sources")
+ return self._get_or_set_stats('_nb_documents', update)
+
+ def _nb_documents(self):
+ from archaeological_context_records.models import ContextRecordSource
+ from archaeological_finds.models import FindSource
+ nbs = self.source.count() + \
+ ContextRecordSource.objects.filter(
+ context_record__operation=self).count() + \
+ FindSource.objects.filter(
+ find__base_finds__context_record__operation=self).count()
+ return nbs
+
+ @property
+ def nb_documents_by_types(self, update=False):
+ return self._get_or_set_stats('_nb_documents_by_types', update)
+
+ def _nb_documents_by_types(self):
+ from archaeological_context_records.models import ContextRecordSource
+ from archaeological_finds.models import FindSource
+ docs = {}
+
+ qs = [
+ self.source,
+ ContextRecordSource.objects.filter(context_record__operation=self),
+ FindSource.objects.filter(
+ find__base_finds__context_record__operation=self)]
+ for q in qs:
+ for res in q.values('source_type').distinct():
+ st = res['source_type']
+ if st not in docs:
+ docs[st] = 0
+ docs[st] += q.filter(source_type=st).count()
+ docs = [(unicode(SourceType.objects.get(pk=k)), docs[k]) for k in docs]
+ return sorted(docs, key=lambda x: x[0])
+
+ @property
+ def nb_stats_finds_by_ue(self, update=False):
+ return self._get_or_set_stats('_nb_stats_finds_by_ue', update)
+
+ def _nb_stats_finds_by_ue(self):
+ _(u"Mean")
+ res, finds = {}, []
+ for cr in self.context_record.all():
+ finds.append(cr.base_finds.count())
+ if not finds:
+ return res
+ res['mean'] = float(sum(finds)) / max(len(finds), 1)
+ res['min'] = min(finds)
+ res['max'] = max(finds)
+ res['mode'] = u" ; ".join([str(m) for m in mode(finds)])
+ return res
+
+
m2m_changed.connect(cached_label_changed, sender=Operation.towns.through)