summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_finds/migrations/0105_auto_20200407_1414.py6
-rw-r--r--archaeological_finds/models_finds.py2
-rw-r--r--archaeological_warehouse/migrations/0103_auto_container_views.py13
-rw-r--r--archaeological_warehouse/models.py57
-rw-r--r--archaeological_warehouse/templates/ishtar/sheet_warehouse.html251
-rw-r--r--archaeological_warehouse/templates/ishtar/wizard/wizard_warehouse_divisions.html2
6 files changed, 203 insertions, 128 deletions
diff --git a/archaeological_finds/migrations/0105_auto_20200407_1414.py b/archaeological_finds/migrations/0105_auto_20200407_1414.py
index b4c05ee8a..1f9bc88d3 100644
--- a/archaeological_finds/migrations/0105_auto_20200407_1414.py
+++ b/archaeological_finds/migrations/0105_auto_20200407_1414.py
@@ -23,4 +23,10 @@ class Migration(migrations.Migration):
name='collection',
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_warehouse.Warehouse', verbose_name='Collection'),
),
+ migrations.AlterField(
+ model_name='materialtype',
+ name='code',
+ field=models.CharField(blank=True, max_length=100, null=True,
+ verbose_name='Code'),
+ ),
]
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 646ae8088..c18b2f4f1 100644
--- a/archaeological_finds/models_finds.py
+++ b/archaeological_finds/models_finds.py
@@ -55,7 +55,7 @@ from archaeological_warehouse.models import Warehouse
class MaterialType(HierarchicalType):
- code = models.CharField(_("Code"), max_length=10, blank=True, null=True)
+ code = models.CharField(_("Code"), max_length=100, blank=True, null=True)
recommendation = models.TextField(_("Recommendation"), blank=True,
null=True)
diff --git a/archaeological_warehouse/migrations/0103_auto_container_views.py b/archaeological_warehouse/migrations/0103_auto_container_views.py
index f49b7be1f..eb2b32e5e 100644
--- a/archaeological_warehouse/migrations/0103_auto_container_views.py
+++ b/archaeological_warehouse/migrations/0103_auto_container_views.py
@@ -2,7 +2,7 @@
# Generated by Django 1.11.27 on 2020-04-08 18:23
from __future__ import unicode_literals
-from django.db import migrations
+from django.db import migrations, models
import archaeological_warehouse.models
import archaeological_finds.models
@@ -35,4 +35,15 @@ class Migration(migrations.Migration):
migrations.RunSQL(
archaeological_finds.models.FindInsideContainer.CREATE_SQL),
migrations.RunPython(migrate_to_collections),
+ migrations.CreateModel(
+ name='ContainerTree',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True,
+ serialize=False, verbose_name='ID')),
+ ],
+ options={
+ 'db_table': 'containers_tree',
+ 'managed': False,
+ },
+ ),
]
diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py
index a99db2ef7..41ec901a4 100644
--- a/archaeological_warehouse/models.py
+++ b/archaeological_warehouse/models.py
@@ -208,7 +208,7 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
@property
def number_of_finds(self):
from archaeological_finds.models import Find
- return Find.objects.filter(container__responsible=self).count()
+ return Find.objects.filter(container_ref__location=self).count()
@property
def number_of_finds_hosted(self):
@@ -223,14 +223,16 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
if not remaining_division:
return [current_path]
current_division = remaining_division.pop(0)
- q = ContainerLocalisation.objects.filter(
- division=current_division,
+
+ base_q = Container.objects.filter(
+ container_type=current_division,
+ location=self
)
+ q = base_q
for div, ref in current_path:
- q = q.filter(
- container__division__division=div,
- container__division__reference=ref
- )
+ q = base_q.filter(
+ parent__container_type=div,
+ parent__reference=ref)
res = []
old_ref = None
if not q.count():
@@ -252,26 +254,28 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
: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())
+ divisions = [
+ wd.container_type
+ for wd in 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'):
+ def _number_of_items_by_place(self, model, division_key):
res = {}
paths = self.available_division_tuples[:]
for path in paths:
- q = model.objects
cpath = []
for division, ref in path:
+ q = model.objects
cpath.append(ref)
attrs = {
- division_key + "__division": division,
- division_key + "__reference": ref
+ division_key + "container_type": division,
+ division_key + "reference": ref
}
q = q.filter(**attrs)
if tuple(cpath) not in res:
- res[tuple(cpath)] = q.count()
+ res[tuple(cpath)] = q.distinct().count()
res = [(k, res[k]) for k in res]
final_res, current_res, depth = [], [], 1
len_divisions = WarehouseDivisionLink.objects.filter(
@@ -283,7 +287,7 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
depth = len(path)
if path[-1] == '-':
continue
- path = list(path) + ['' for idx in range(len_divisions - len(path))]
+ path = list(path) + ['' for __ in range(len_divisions - len(path))]
current_res.append((path, nb))
final_res.append(current_res[:])
return final_res
@@ -291,14 +295,15 @@ class Warehouse(Address, DocumentItem, GeoItem, QRCodeItem, DashboardFormItem,
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')
+ Find, division_key='inside_container__container__')
@property
def number_of_finds_by_place(self, update=False):
return self._get_or_set_stats('_number_of_finds_by_place', update)
def _number_of_containers_by_place(self):
- return self._number_of_items_by_place(Container)
+ return self._number_of_items_by_place(
+ ContainerTree, 'container_parent__')
@property
def number_of_containers_by_place(self, update=False):
@@ -421,7 +426,7 @@ class WarehouseDivisionLink(models.Model):
return self.warehouse.uuid, self.container_type.txt_idx
-class ContainerTree:
+class ContainerTree(models.Model):
CREATE_SQL = """
CREATE VIEW containers_tree AS
WITH RECURSIVE rel_tree AS (
@@ -458,6 +463,17 @@ class ContainerTree:
DROP VIEW IF EXISTS container_tree;
DROP VIEW IF EXISTS containers_tree;
"""
+ container = models.OneToOneField(
+ "archaeological_warehouse.Container", verbose_name=_("Container"),
+ related_name="container_tree_child", primary_key=True)
+ container_parent = models.ForeignKey(
+ "archaeological_warehouse.Container",
+ verbose_name=_("Container parent"),
+ related_name="container_tree_parent")
+
+ class Meta:
+ managed = False
+ db_table = 'containers_tree'
class Container(DocumentItem, Merge, LightHistorizedItem, QRCodeItem, GeoItem,
@@ -795,8 +811,7 @@ class Container(DocumentItem, Merge, LightHistorizedItem, QRCodeItem, GeoItem,
@classmethod
def get_query_owns(cls, ishtaruser):
return Q(history_creator=ishtaruser.user_ptr) | \
- Q(location__person_in_charge__ishtaruser=ishtaruser) | \
- Q(responsible__person_in_charge__ishtaruser=ishtaruser)
+ Q(location__person_in_charge__ishtaruser=ishtaruser)
def get_precise_points(self):
precise_points = super(Container, self).get_precise_points()
diff --git a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
index feb8b786a..1307425ff 100644
--- a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
+++ b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html
@@ -8,124 +8,167 @@
{% block content %}
-<div class="row">
- <div class="offset-lg-4 col-lg-4 offset-md-3 col-md-6 offset-sm-1 col-sm-10 col-12">
- <div class="card">
- {% include "ishtar/blocks/window_image.html" %}
- <div class="card-body">
- <p class="card-text">
- <p class="window-refs">
- <strong>{{ item.name|default:"" }}</strong>
- </p>
- <p class="window-refs">
- {{ item.warehouse_type|default:"" }}
- </p>
- {% include "ishtar/blocks/sheet_external_id.html" %}
- </p>
+
+{% if output != "ODT" and output != "PDF"%}
+<ul class="nav nav-tabs" id="{{window_id}}-tabs" role="tablist">
+ <li class="nav-item">
+ <a class="nav-link active" id="{{window_id}}-general-tab"
+ data-toggle="tab" href="#{{window_id}}-general" role="tab"
+ aria-controls="{{window_id}}-general" aria-selected="true">
+ {% trans "General" %}
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-content-tab"
+ data-toggle="tab" href="#{{window_id}}-content" role="tab"
+ aria-controls="{{window_id}}-content" aria-selected="true">
+ {% trans "Content" %}
+ </a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" id="{{window_id}}-stats-tab"
+ data-toggle="tab" href="#{{window_id}}-stats" role="tab"
+ aria-controls="{{window_id}}-stats" aria-selected="false">
+ {% trans "Statistics" %}
+ </a>
+ </li>
+</ul>
+{% endif %}
+
+<div class="tab-content" id="{{window_id}}-tab-content">
+
+ <div class="tab-pane fade show active" id="{{window_id}}-general"
+ role="tabpanel" aria-labelledby="{{window_id}}-general-tab">
+ <div class="row">
+ <div class="offset-lg-4 col-lg-4 offset-md-3 col-md-6 offset-sm-1 col-sm-10 col-12">
+ <div class="card">
+ {% include "ishtar/blocks/window_image.html" %}
+ <div class="card-body">
+ <div class="card-text">
+ <p class="window-refs">
+ <strong>{{ item.name|default:"" }}</strong>
+ </p>
+ <p class="window-refs">
+ {{ item.warehouse_type|default:"" }}
+ </p>
+ {% include "ishtar/blocks/sheet_external_id.html" %}
+ </div>
+ </div>
+ </div>
</div>
</div>
- </div>
-</div>
-<div class='row'>
- {% include "ishtar/blocks/sheet_creation_section.html" %}
- {% field_flex_detail "Person in charge" item.person_in_charge %}
- {% field_flex_detail "Organization" item.organization %}
- {% trans "Default divisions" as def_div_label %}
- {% field_flex def_div_label item.location_types|join:", " %}
- {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
- {% include "ishtar/blocks/sheet_json.html" %}
-</div>
+ <div class='row'>
+ {% include "ishtar/blocks/sheet_creation_section.html" %}
+ {% field_flex_detail "Person in charge" item.person_in_charge %}
+ {% field_flex_detail "Organization" item.organization %}
+ {% trans "Default divisions" as def_div_label %}
+ {% field_flex def_div_label item.location_types|join:", " %}
+ {% field_flex_full "Comment" item.comment "<pre>" "</pre>" %}
+ {% include "ishtar/blocks/sheet_json.html" %}
+ </div>
-{% if item.point_2d or item.multi_polygon or item.get_address or item.get_address_complement or item.get_postal_code or item.get_town %}
-<h3>{% trans "Localisation"%}</h3>
-<div class='row'>
- {% with geo_item=item %}
- {% if PROFILE.locate_warehouses %}{% include "ishtar/blocks/sheet_simple_map.html"%}{% endif %}
- <div class="col-12 col-lg-6 flex-wrap">
- {% if PROFILE.locate_warehouses %}{% include "ishtar/blocks/sheet_coordinates.html"%}{% endif %}
- {% with full=True %}{% include "ishtar/blocks/sheet_address_section.html" %}{% endwith %}
+ {% if item.point_2d or item.multi_polygon or item.get_address or item.get_address_complement or item.get_postal_code or item.get_town %}
+ <h3>{% trans "Localisation"%}</h3>
+ <div class='row'>
+ {% with geo_item=item %}
+ {% if PROFILE.locate_warehouses %}{% include "ishtar/blocks/sheet_simple_map.html"%}{% endif %}
+ <div class="col-12 col-lg-6 flex-wrap">
+ {% if PROFILE.locate_warehouses %}{% include "ishtar/blocks/sheet_coordinates.html"%}{% endif %}
+ {% with full=True %}{% include "ishtar/blocks/sheet_address_section.html" %}{% endwith %}
+ </div>
+ {% endwith %}
+ </div>
+ {% endif %}
</div>
- {% endwith %}
-</div>
-{% endif %}
-
-{% if item.containers.count %}
-<h4>{% trans "Containers" %}</h4>
-{% dynamic_table_document '' 'containers' 'location_id' item.pk 'TABLE_COLS' output %}
-{% endif %}
+ <div class="tab-pane fade" id="{{window_id}}-content"
+ role="tabpanel" aria-labelledby="{{window_id}}-content-tab">
+ {% if item.containers.count %}
+ <h4>{% trans "Containers" %}</h4>
+ {% dynamic_table_document '' 'containers' 'location_id' item.pk 'TABLE_COLS' output %}
+ {% else %}
+ <div class="alert alert-info">
+ <i class="fa fa-exclamation-triangle"></i>
+ {% trans "No container inside this warehouse" %}
+ </div>
+ {% endif %}
+ </div>
-<h3>{% trans "Statistics" %}</h3>
-<small class="centered"><em>{% trans "These numbers are updated hourly" %}</em></small>
-
-<h4>{% trans "Finds" %}</h4>
-<div class='row'>
- {% trans "Number of attached finds" as number_of_attached_finds_label %}
- {% field_flex_2 number_of_attached_finds_label item.number_of_finds %}
- {% trans "Number of hosted finds" as number_of_hosted_finds_label %}
- {% field_flex_2 number_of_hosted_finds_label item.number_of_finds_hosted %}
-</div>
+ <div class="tab-pane fade" id="{{window_id}}-stats"
+ role="tabpanel" aria-labelledby="{{window_id}}-stats-tab">
+ <h3>{% trans "Statistics" %}</h3>
+ <small class="centered"><em>{% trans "These numbers are updated hourly" %}</em></small>
+
+ <h4>{% trans "Finds" %}</h4>
+ <div class='row'>
+ {% trans "Number of attached finds" as number_of_attached_finds_label %}
+ {% field_flex_2 number_of_attached_finds_label item.number_of_finds %}
+ {% trans "Number of hosted finds" as number_of_hosted_finds_label %}
+ {% field_flex_2 number_of_hosted_finds_label item.number_of_finds_hosted %}
+ </div>
-{% if item.number_of_finds_by_place %}
-<h4>{% trans "Finds by location in the warehouse" %}</h4>
-{% for items in item.number_of_finds_by_place %}
-{% if items %}
-<table class='table table-striped datatables'
- id="{{window_id}}-find-by-loca-{{forloop.counter}}">
- <thead>
- <tr>{% for location_type in item.location_types %}
- <th class="text-center">{{location_type|title}}</th>{% endfor %}
- <th class="text-center">{% trans "Total" %}</th>
- </tr>
- </thead>
- <tbody>
- {% for item in items %}
- <tr>
- {% for local in item.0 %}<td>{{local}}</td>{% endfor %}
- <td class="text-right">{{item.1}}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% endif %}
-{% endfor %}
-{% endif %}
+ {% if item.number_of_finds_by_place %}
+ <h4>{% trans "Finds by location in the warehouse" %}</h4>
+ {% for items in item.number_of_finds_by_place %}
+ {% if items %}
+ <table class='table table-striped datatables'
+ id="{{window_id}}-find-by-loca-{{forloop.counter}}">
+ <thead>
+ <tr>{% for location_type in item.location_types %}
+ <th class="text-center">{{location_type|title}}</th>{% endfor %}
+ <th class="text-center">{% trans "Total" %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for item in items %}
+ <tr>
+ {% for local in item.0 %}<td>{{local}}</td>{% endfor %}
+ <td class="text-right">{{item.1}}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+
+ <h4>{% trans "Containers" %}</h4>
+ <div class='row'>
+ {% trans "Number of containers" as number_of_containers_label %}
+ {% field_flex_2 number_of_containers_label item.number_of_containers %}
+ </div>
-<h4>{% trans "Containers" %}</h4>
-<div class='row'>
- {% trans "Number of containers" as number_of_containers_label %}
- {% field_flex_2 number_of_containers_label item.number_of_containers %}
+ {% if item.number_of_containers_by_place %}
+ <h4>{% trans "Containers by location in the warehouse" %}</h4>
+ {% for items in item.number_of_containers_by_place %}
+ {% if items %}
+ <table class='table table-striped datatables'
+ id="{{window_id}}-container-by-loca-{{forloop.counter}}">
+ <thead>
+ <tr>{% for location_type in item.location_types %}
+ <th class="text-center">{{location_type|title}}</th>{% endfor %}
+ <th class="text-center">{% trans "Total" %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for item in items %}
+ <tr>
+ {% for local in item.0 %}<td class="text-center">{{local}}</td>{% endfor %}
+ <td class="text-center">{{item.1}}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+ </div>
</div>
-{% if item.number_of_containers_by_place %}
-<h4>{% trans "Containers by location in the warehouse" %}</h4>
-{% for items in item.number_of_containers_by_place %}
-{% if items %}
-<table class='table table-striped datatables'
- id="{{window_id}}-container-by-loca-{{forloop.counter}}">
- <thead>
- <tr>{% for location_type in item.location_types %}
- <th class="text-center">{{location_type|title}}</th>{% endfor %}
- <th class="text-center">{% trans "Total" %}</th>
- </tr>
- </thead>
- <tbody>
- {% for item in items %}
- <tr>
- {% for local in item.0 %}<td class="text-center">{{local}}</td>{% endfor %}
- <td class="text-center">{{item.1}}</td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% endif %}
-{% endfor %}
-{% endif %}
-
<script type="text/javascript">
$(document).ready( function () {
datatable_options = {
diff --git a/archaeological_warehouse/templates/ishtar/wizard/wizard_warehouse_divisions.html b/archaeological_warehouse/templates/ishtar/wizard/wizard_warehouse_divisions.html
index dff23bc6c..2b11e9235 100644
--- a/archaeological_warehouse/templates/ishtar/wizard/wizard_warehouse_divisions.html
+++ b/archaeological_warehouse/templates/ishtar/wizard/wizard_warehouse_divisions.html
@@ -3,6 +3,6 @@
{% block form_head %}
<div class="alert alert-info">
<i class="fa fa-exclamation-triangle"></i>
- {% trans "Default division for this warehouse. Theses divisions are only used for imports." %}<br/>
+ {% trans "Default division for this warehouse. Theses divisions are only used for imports and statistics." %}<br/>
</div>
{% endblock %}