summaryrefslogtreecommitdiff
path: root/archaeological_warehouse
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_warehouse')
-rw-r--r--archaeological_warehouse/migrations/0104_auto_20200925_1024.py31
-rw-r--r--archaeological_warehouse/models.py102
-rw-r--r--archaeological_warehouse/templates/ishtar/sheet_warehouse.html4
3 files changed, 101 insertions, 36 deletions
diff --git a/archaeological_warehouse/migrations/0104_auto_20200925_1024.py b/archaeological_warehouse/migrations/0104_auto_20200925_1024.py
new file mode 100644
index 000000000..f82b25b19
--- /dev/null
+++ b/archaeological_warehouse/migrations/0104_auto_20200925_1024.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.27 on 2020-09-25 10:24
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('archaeological_warehouse', '0103_auto_container_views'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='historicalwarehouse',
+ name='max_division_number',
+ field=models.IntegerField(default=0, help_text='Automatically generated', verbose_name='Number maximum of division'),
+ ),
+ migrations.AddField(
+ model_name='warehouse',
+ name='max_division_number',
+ field=models.IntegerField(default=0, help_text='Automatically generated', verbose_name='Number maximum of division'),
+ ),
+ migrations.AlterField(
+ model_name='container',
+ name='container_type',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='containers', to='archaeological_warehouse.ContainerType', verbose_name='Container type'),
+ ),
+ ]
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index 096ff0b6c..870f10d95 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -25,7 +25,7 @@ from django.conf import settings
from django.contrib.gis.db import models
from django.contrib.postgres.indexes import GinIndex
from django.core.urlresolvers import reverse
-from django.db.models import Q, Max
+from django.db.models import Q, Max, Count
from django.db.models.signals import post_save, post_delete, m2m_changed
from django.template.defaultfilters import slugify
from ishtar_common.utils import ugettext_lazy as _, pgettext_lazy
@@ -131,6 +131,9 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
external_id = models.TextField(_("External ID"), blank=True, null=True)
auto_external_id = models.BooleanField(
_("External ID is set automatically"), default=False)
+ max_division_number = models.IntegerField(
+ _("Number maximum of division"), default=0,
+ help_text=_("Automatically generated"))
SUB_ADDRESSES = ["organization", "person_in_charge"]
class Meta:
@@ -190,10 +193,11 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
@property
def location_types(self):
+ if not self.max_division_number:
+ return []
return [
- wd.container_type.label
- for wd in WarehouseDivisionLink.objects.filter(
- warehouse=self).order_by('order').all() if wd.container_type
+ "{} {}".format(_("Division"), idx + 1)
+ for idx in range(self.max_division_number)
]
@property
@@ -227,33 +231,53 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
def _get_divisions(self, current_path, remaining_division, depth=0):
if not remaining_division:
return [current_path]
- current_division = remaining_division.pop(0)
+ remaining_division.pop(0)
- base_q = Container.objects.filter(
- container_type=current_division,
- location=self
- )
- q = base_q
- for div, ref in current_path:
- q = base_q.filter(
- parent__container_type=div,
- parent__reference=ref)
+ query_location = "location"
+ for __ in range(depth):
+ query_location = "parent__" + query_location
+ base_q = Container.objects.filter(**{query_location: self})
+
+ q = base_q.annotate(nb_children=Count("children__id")).exclude(
+ nb_children=0)
+
+ if not current_path:
+ q = q.annotate(nb_parent=Count("parent__id")).filter(
+ nb_parent=0)
+
+ for idx, p in enumerate(reversed(current_path)):
+ parent_id, __ = p
+ key = "parent__" * (idx + 1) + "id"
+ q = q.filter(**{key: parent_id})
res = []
- old_ref = None
+ old_ref, ct = None, None
if not q.count():
return [current_path]
- for ref in q.values('reference').order_by('reference').all():
- if ref['reference'] == old_ref:
+ q = q.values(
+ 'id', 'reference', 'container_type__label', 'container_type_id'
+ ).order_by('container_type__label', 'reference')
+
+ DIVISION_TEMPLATE = """<a class="display_details"
+ href="#" onclick="load_window('/show-container/{id}/')">
+ <i class="fa fa-info-circle" aria-hidden="true"></i></a>
+ {container} {ref}"""
+ for ref in q.all():
+ if ref['reference'] == old_ref and \
+ ref["container_type__label"] == ct:
continue
old_ref = ref['reference']
+ ct = ref["container_type__label"]
cpath = current_path[:]
- cpath.append((current_division, ref['reference']))
+ lbl = DIVISION_TEMPLATE.format(
+ id=ref["id"], container=ref["container_type__label"],
+ ref=ref['reference'])
+ cpath.append((ref["id"], lbl))
remaining_division = list(
ContainerType.objects.filter(
containers__parent__reference=ref['reference'],
- containers__parent__container_type=current_division,
- containers__location=self,
- stationary=True).distinct())
+ containers__parent__container_type_id=ref[
+ "container_type_id"],
+ containers__location=self).distinct())
for r in self._get_divisions(cpath, remaining_division[:],
depth + 1):
res.append(r)
@@ -263,7 +287,7 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
def available_division_tuples(self):
"""
:return: ordered list of available paths. Each path is a list of
- tuple with the container type and the reference.
+ tuple with the container type and the full reference.
"""
top_divisions = list(
ContainerType.objects.filter(
@@ -278,20 +302,16 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
paths = self.available_division_tuples[:]
for path in paths:
cpath = []
- cdiv_path = []
- for division, ref in path:
- cpath.append(ref)
- cdiv_path.append(division)
+ for container_id, lbl in path:
+ cpath.append((container_id, lbl))
if tuple(cpath) in res:
continue
q = model.objects
- reversed_cdiv = list(reversed(cdiv_path))
- for idx, new_ref in enumerate(reversed(cpath)):
- division = reversed_cdiv[idx]
+ for idx, p in enumerate(reversed(cpath)):
+ container_id, __ = p
div_key = division_key + "parent__" * idx
attrs = {
- div_key + "container_type": division,
- div_key + "reference": new_ref
+ div_key + "id": container_id
}
q = q.filter(**attrs)
if count_filter:
@@ -300,16 +320,18 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
res = [(k, res[k]) for k in res]
final_res, current_res, depth = [], [], 1
- len_divisions = WarehouseDivisionLink.objects.filter(
- warehouse=self).count()
+ len_divisions = self.max_division_number
for path, nb in sorted(res, key=lambda x: (len(x[0]), x[0])):
+ if len(path) > len_divisions:
+ continue
if depth != len(path):
final_res.append(current_res[:])
current_res = []
depth = len(path)
if path[-1] == '-':
continue
- path = list(path) + ['' for __ in range(len_divisions - len(path))]
+ path = [k[1] for k in path]
+ path = path + ['' for __ in range(len_divisions - len(path))]
current_res.append((path, nb))
final_res.append(current_res[:])
return final_res
@@ -1173,10 +1195,22 @@ class Container(DocumentItem, Merge, LightHistorizedItem, QRCodeItem, GeoItem,
else:
self.index = 1
+ def _update_warehouse_max_division(self):
+ number = 0
+ parent = self.parent_id
+ while parent:
+ number += 1
+ parent = Container.objects.filter(pk=parent).values_list(
+ "parent_id")[0][0]
+ if number > self.location.max_division_number:
+ self.location.max_division_number = number
+ self.location.save()
+
def save(self, *args, **kwargs):
self.pre_save()
super(Container, self).save(*args, **kwargs)
self._change_child_location(self)
+ self._update_warehouse_max_division()
updated = False
if not self.index:
diff --git a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
index dcaa12215..b6f93cc57 100644
--- a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
+++ b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
@@ -144,7 +144,7 @@
<tbody>
{% for item in items %}
<tr>
- {% for local in item.0 %}<td>{{local}}</td>{% endfor %}
+ {% for local in item.0 %}<td>{{local|safe}}</td>{% endfor %}
<td class="text-right">{{item.1}}</td>
</tr>
{% endfor %}
@@ -175,7 +175,7 @@
<tbody>
{% for item in items %}
<tr>
- {% for local in item.0 %}<td class="text-center">{{local}}</td>{% endfor %}
+ {% for local in item.0 %}<td>{{local|safe}}</td>{% endfor %}
<td class="text-center">{{item.1}}</td>
</tr>
{% endfor %}