summaryrefslogtreecommitdiff
path: root/archaeological_warehouse/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2017-04-05 11:33:54 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2017-04-05 11:33:54 +0200
commit2e512bc9dffca5624342aa75ca01b3ff7f390141 (patch)
tree21976a27b67c98aa1a79a63f190d06dd489b89ec /archaeological_warehouse/models.py
parent3a5dbf688d058bd39aaae308cd7224ddd42c7890 (diff)
downloadIshtar-2e512bc9dffca5624342aa75ca01b3ff7f390141.tar.bz2
Ishtar-2e512bc9dffca5624342aa75ca01b3ff7f390141.zip
Warehouse sheet: provide statistics (refs #3398)
- Number of finds (total and by places) - Number of container (total and by places)
Diffstat (limited to 'archaeological_warehouse/models.py')
-rw-r--r--archaeological_warehouse/models.py103
1 files changed, 99 insertions, 4 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index fe054a37b..2851e1df0 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -21,7 +21,7 @@ import datetime
from django.conf import settings
from django.contrib.gis.db import models
-from django.db.models import Q
+from django.db.models import Q, Count
from django.db.models.signals import post_save, post_delete
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _, ugettext
@@ -29,7 +29,9 @@ from django.utils.translation import ugettext_lazy as _, ugettext
from ishtar_common.utils import cached_label_changed
from ishtar_common.models import GeneralType, get_external_id, \
- LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, ImageModel
+ LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, \
+ ImageModel, DashboardFormItem
+from archaeological_finds.models import Find
class WarehouseType(GeneralType):
@@ -41,7 +43,7 @@ post_save.connect(post_save_cache, sender=WarehouseType)
post_delete.connect(post_save_cache, sender=WarehouseType)
-class Warehouse(Address, OwnPerms):
+class Warehouse(Address, DashboardFormItem, OwnPerms):
SHOW_URL = 'show-warehouse'
name = models.CharField(_(u"Name"), max_length=200)
warehouse_type = models.ForeignKey(WarehouseType,
@@ -83,6 +85,98 @@ class Warehouse(Address, OwnPerms):
def get_query_owns(cls, user):
return Q(person_in_charge__ishtaruser=user.ishtaruser)
+ @property
+ def number_of_finds(self):
+ return Find.objects.filter(container__responsible=self).count()
+
+ @property
+ def number_of_finds_hosted(self):
+ return Find.objects.filter(container__location=self).count()
+
+ @property
+ def number_of_containers(self):
+ return Container.objects.filter(location=self).count()
+
+ def _get_divisions(self, current_path, remaining_division, depth=0):
+ if not remaining_division:
+ return [current_path]
+ current_division = remaining_division.pop(0)
+ q = ContainerLocalisation.objects.filter(
+ division=current_division,
+ )
+ for div, ref in current_path:
+ q = q.filter(
+ container__division__division=div,
+ container__division__reference=ref
+ )
+ res = []
+ old_ref = None
+ for ref in q.values('reference').order_by('reference').all():
+ if ref['reference'] == old_ref:
+ continue
+ old_ref = ref['reference']
+ cpath = current_path[:]
+ cpath.append((current_division, ref['reference']))
+ for r in self._get_divisions(cpath, remaining_division[:],
+ depth + 1):
+ res.append(r)
+ return res
+
+ @property
+ def available_division_tuples(self):
+ """
+ :return: ordered list of available paths. Each path is a list of
+ tuple with the WarehouseDivisionLink and the reference.
+ """
+ divisions = list(
+ WarehouseDivisionLink.objects.filter(warehouse=self
+ ).order_by('order').all())
+ return self._get_divisions([], divisions)
+
+ def _number_of_items_by_place(self, model, division_key='division'):
+ res = {}
+ paths = self.available_division_tuples[:]
+ for path in paths:
+ q = model.objects
+ cpath = []
+ for division, ref in path:
+ lbl = u"{} {}".format(division.division, ref)
+ cpath.append(lbl)
+ attrs = {
+ division_key + "__division": division,
+ division_key + "__reference": ref
+ }
+ q = q.filter(**attrs)
+ if tuple(cpath) not in res:
+ res[tuple(cpath)] = q.count()
+ res = [(k, res[k]) for k in res]
+ final_res, current_res, depth = [], [], 1
+ for path, nb in sorted(res, key=lambda x: (len(x[0]), x[0])):
+ if depth != len(path):
+ final_res.append(current_res[:])
+ current_res = []
+ depth = len(path)
+ current_res.append((u" | ".join(path), nb))
+ final_res.append(current_res[:])
+ return final_res
+
+ def _number_of_finds_by_place(self):
+ return self._number_of_items_by_place(
+ Find, division_key='container__division')
+
+ @property
+ def number_of_finds_by_place(self, update=False):
+ return self._get_or_set_stats('_number_of_finds_by_place', update,
+ settings.CACHE_SMALLTIMEOUT)
+
+ def _number_of_containers_by_place(self):
+ return self._number_of_items_by_place(Container)
+
+ @property
+ def number_of_containers_by_place(self, update=False):
+ return self._get_or_set_stats('_number_of_containers_by_place', update,
+ settings.CACHE_SMALLTIMEOUT)
+
def save(self, *args, **kwargs):
super(Warehouse, self).save(*args, **kwargs)
for container in self.containers.all():
@@ -287,7 +381,8 @@ post_save.connect(cached_label_changed, sender=Container)
class ContainerLocalisation(models.Model):
- container = models.ForeignKey(Container, verbose_name=_(u"Container"))
+ container = models.ForeignKey(Container, verbose_name=_(u"Container"),
+ related_name='division')
division = models.ForeignKey(WarehouseDivisionLink,
verbose_name=_(u"Division"))
reference = models.CharField(_(u"Reference"), max_length=200, default='')