summaryrefslogtreecommitdiff
path: root/archaeological_warehouse/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_warehouse/models.py')
-rw-r--r--archaeological_warehouse/models.py114
1 files changed, 111 insertions, 3 deletions
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index d1918f46a..96814339c 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -21,6 +21,7 @@ import datetime
from django.conf import settings
from django.contrib.gis.db import models
+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
@@ -28,7 +29,8 @@ 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
class WarehouseType(GeneralType):
@@ -40,7 +42,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,
@@ -78,6 +80,105 @@ class Warehouse(Address, OwnPerms):
return datetime.date.today().strftime('%Y-%m-%d') + '-' + \
slugify(unicode(self))
+ @classmethod
+ def get_query_owns(cls, user):
+ return Q(person_in_charge__ishtaruser=user.ishtaruser)
+
+ @property
+ def number_of_finds(self):
+ from archaeological_finds.models import Find
+ return Find.objects.filter(container__responsible=self).count()
+
+ @property
+ def number_of_finds_hosted(self):
+ from archaeological_finds.models import Find
+ 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):
+ from archaeological_finds.models import Find
+ 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():
@@ -208,6 +309,12 @@ class Container(LightHistorizedItem, ImageModel):
cached_label = u" - ".join(items)
return cached_label
+ @classmethod
+ def get_query_owns(cls, user):
+ return Q(history_creator=user) | \
+ Q(location__person_in_charge__ishtaruser=user.ishtaruser) | \
+ Q(responsible__person_in_charge__ishtaruser=user.ishtaruser)
+
@property
def associated_filename(self):
filename = datetime.date.today().strftime('%Y-%m-%d')
@@ -276,7 +383,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='')