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