diff options
Diffstat (limited to 'archaeological_operations/models.py')
-rw-r--r-- | archaeological_operations/models.py | 198 |
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) |