summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2025-09-26 16:38:26 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2025-09-29 17:54:01 +0200
commit4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9 (patch)
tree3eda90e6536090906547e93024d79c9c55c2f571
parent447c972cf4f9f99c02434b96097d0e914d96056c (diff)
downloadIshtar-4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9.tar.bz2
Ishtar-4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9.zip
✨ sheet operation: find statistics with number of remains
-rw-r--r--archaeological_operations/models.py73
-rw-r--r--archaeological_operations/templates/ishtar/sheet_operation.html39
-rw-r--r--archaeological_operations/views.py7
3 files changed, 72 insertions, 47 deletions
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 48bdfb450..614ee69aa 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -31,7 +31,7 @@ from django.contrib.gis.db.models.functions import Centroid
from django.contrib.postgres.indexes import GinIndex
from django.contrib.sites.models import Site
from django.db import transaction, OperationalError, IntegrityError
-from django.db.models import Q, Max
+from django.db.models import Q, Max, Sum
from django.db.models.signals import post_save, m2m_changed, post_delete
from django.forms import ValidationError
from django.urls import reverse, reverse_lazy
@@ -2500,12 +2500,26 @@ class Operation(
return q.count()
@property
- def nb_finds_by_material_type(self, update=False):
+ def nb_remains(self, update=False):
+ _("Number of remains")
+ return self._get_or_set_stats("_nb_remains", update)
+
+ def _nb_remains(self):
+ Find = apps.get_model("archaeological_finds", "Find")
+ q = Find.objects.filter(
+ base_finds__context_record__operation=self,
+ upstream_treatment_id__isnull=True,
+ find_number__isnull=False
+ ).distinct()
+ return q.aggregate(Sum("find_number"))["find_number__sum"]
+
+ @property
+ def nb_finds_by_material_type_full(self, update=False):
return self._get_or_set_stats(
- "_nb_finds_by_material_type", update, expected_type=list
+ "_nb_finds_by_material_type_full", update, expected_type=list
)
- def _nb_finds_by_material_type(self):
+ def _nb_finds_by_material_type_full(self):
Find = apps.get_model("archaeological_finds", "Find")
nbs = []
@@ -2520,23 +2534,26 @@ class Operation(
.order_by("material_types__label")
)
for res in q.all():
- nbs.append(
- (
- str(res["material_types__label"] or "-"),
- Find.objects.filter(
+ q2 = Find.objects.filter(
base_finds__context_record__operation=self,
upstream_treatment_id__isnull=True,
material_types__pk=res["material_types__pk"],
- ).count(),
+ )
+ q3 = q2.filter(find_number__isnull=False)
+ nbs.append(
+ (
+ str(res["material_types__label"] or "-"),
+ q2.count(),
+ q3.aggregate(Sum("find_number"))["find_number__sum"],
)
)
return nbs
@property
- def nb_finds_by_types(self, update=False):
- return self._get_or_set_stats("_nb_finds_by_types", update, expected_type=list)
+ def nb_finds_by_types_full(self, update=False):
+ return self._get_or_set_stats("_nb_finds_by_types_full", update, expected_type=list)
- def _nb_finds_by_types(self):
+ def _nb_finds_by_types_full(self):
Find = apps.get_model("archaeological_finds", "Find")
nbs = []
@@ -2550,25 +2567,28 @@ class Operation(
label = str(res["object_types__label"])
if label == "None":
label = str(_("No type"))
+ q2 = Find.objects.filter(
+ base_finds__context_record__operation=self,
+ upstream_treatment_id__isnull=True,
+ object_types=res["object_types"],
+ )
+ q3 = q2.filter(find_number__isnull=False)
nbs.append(
(
label,
- Find.objects.filter(
- base_finds__context_record__operation=self,
- upstream_treatment_id__isnull=True,
- object_types=res["object_types"],
- ).count(),
+ q2.count(),
+ q3.aggregate(Sum("find_number"))["find_number__sum"],
)
)
return nbs
@property
- def nb_finds_by_periods(self, update=False):
+ def nb_finds_by_periods_full(self, update=False):
return self._get_or_set_stats(
- "_nb_finds_by_periods", update, expected_type=list
+ "_nb_finds_by_periods_full", update, expected_type=list
)
- def _nb_finds_by_periods(self):
+ def _nb_finds_by_periods_full(self):
Find = apps.get_model("archaeological_finds", "Find")
nbs = []
@@ -2579,14 +2599,17 @@ class Operation(
.order_by("datings__period__order")
)
for res in q.all():
+ q2 = Find.objects.filter(
+ base_finds__context_record__operation=self,
+ upstream_treatment_id__isnull=True,
+ datings__period=res["datings__period"]
+ )
+ q3 = q2.filter(find_number__isnull=False)
nbs.append(
(
str(res["datings__period__label"] or "-"),
- Find.objects.filter(
- base_finds__context_record__operation=self,
- upstream_treatment_id__isnull=True,
- datings__period=res["datings__period"],
- ).count(),
+ q2.count(),
+ q3.aggregate(Sum("find_number"))["find_number__sum"],
)
)
return nbs
diff --git a/archaeological_operations/templates/ishtar/sheet_operation.html b/archaeological_operations/templates/ishtar/sheet_operation.html
index ef9c9632a..e290ce319 100644
--- a/archaeological_operations/templates/ishtar/sheet_operation.html
+++ b/archaeological_operations/templates/ishtar/sheet_operation.html
@@ -1,5 +1,5 @@
{% extends "ishtar/sheet.html" %}
-{% load i18n l10n ishtar_helpers window_tables window_header window_ope_tables window_field from_dict %}
+{% load i18n l10n ishtar_helpers humanize window_tables window_header window_ope_tables window_field from_dict %}
{% block head_title %}<strong>{% trans "Operation" %}</strong> - {{item.short_label}}{% if item.common_name %} - {{item.common_name}}{% endif %}{% endblock %}
@@ -535,12 +535,12 @@
<h4>{% trans "Parcels" %}</h4>
<div class='row'>
- {% field_flex_2 "Number of parcels" item.nb_parcels %}
+ {% field_flex_2 "Number of parcels" item.nb_parcels|intcomma %}
</div>
<h4>{% trans "Context records" %}</h4>
<div class='row'>
- {% field_flex_2 "Number of context records" item.nb_context_records %}
+ {% field_flex_2 "Number of context records" item.nb_context_records|intcomma %}
</div>
<div class='row'>
{% if item.nb_context_records_by_type %}
@@ -548,7 +548,7 @@
<table class="table table-striped">
<tr><th>{% trans "Type" %}</th><th>{% trans "Number" %}</th></tr>
{% for label, nb in item.nb_context_records_by_type %}
- <tr><td>{{label|default:"-"}}</td><td>{{nb}}</td></tr>
+ <tr><td>{{label|default:"-"}}</td><td class="text-right">{{nb}}</td></tr>
{% endfor %}
</table>
</div>
@@ -558,7 +558,7 @@
<table class="table table-striped">
<tr><th>{% trans "Chronological period" %}</th><th>{% trans "Number" %}</th></tr>
{% for label, nb in item.nb_context_records_by_periods %}
- <tr><td>{{label|default:"-"}}</td><td>{{nb}}</td></tr>
+ <tr><td>{{label|default:"-"}}</td><td class="text-right">{{nb}}</td></tr>
{% endfor %}
</table>
</div>
@@ -567,35 +567,36 @@
<h4>{% trans "Finds" %}</h4>
<div class='row'>
- {% field_flex_2 "Number of finds" item.nb_finds %}
+ {% field_flex "Number of finds" item.nb_finds|intcomma %}
+ {% field_flex _("Number of remains") item.nb_remains|intcomma %}
</div>
<div class='row'>
- {% if item.nb_finds_by_material_type %}
+ {% if item.nb_finds_by_material_type_full %}
<div class="col-12 col-md-6 col-lg-4">
<table class="table table-striped">
- <tr><th>{% trans "Material type" %}</th><th>{% trans "Number" %}</th></tr>
- {% for label, nb in item.nb_finds_by_material_type %}
- <tr><td>{{label|default:"-"}}</td><td>{{nb}}</td></tr>
+ <tr><th>{% trans "Material type" %}</th><th>{% trans "Number" %}</th><th>{% trans "Number of remains" %}</th></tr>
+ {% for label, nb, remains in item.nb_finds_by_material_type_full %}
+ <tr><td>{{label|default:"-"}}</td><td class="text-right">{{nb}}</td><td class="text-right">{{remains|default:"-"}}</td></tr>
{% endfor %}
</table>
</div>
{% endif %}
- {% if item.nb_finds_by_types %}
+ {% if item.nb_finds_by_types_full %}
<div class="col-12 col-md-6 col-lg-4">
<table class="table table-striped">
- <tr><th>{% trans "Object type" %}</th><th>{% trans "Number" %}</th></tr>
- {% for label, nb in item.nb_finds_by_types %}
- <tr><td>{{label}}</td><td>{{nb}}</td></tr>
+ <tr><th>{% trans "Object type" %}</th><th>{% trans "Number" %}</th><th>{% trans "Number of remains" %}</th></tr>
+ {% for label, nb, remains in item.nb_finds_by_types_full %}
+ <tr><td>{{label}}</td><td class="text-right">{{nb}}</td><td class="text-right">{{remains|default:"-"}}</td></tr>
{% endfor %}
</table>
</div>
{% endif %}
- {% if item.nb_finds_by_periods %}
+ {% if item.nb_finds_by_periods_full %}
<div class="col-12 col-md-6 col-lg-4">
<table class="table table-striped">
- <tr><th>{% trans "Chronological period" %}</th><th>{% trans "Number" %}</th></tr>
- {% for label, nb in item.nb_finds_by_periods %}
- <tr><td>{{label|default:"-"}}</td><td>{{nb}}</td></tr>
+ <tr><th>{% trans "Chronological period" %}</th><th>{% trans "Number" %}</th><th>{% trans "Number of remains" %}</th></tr>
+ {% for label, nb, remains in item.nb_finds_by_periods_full %}
+ <tr><td>{{label|default:"-"}}</td><td>{{nb}}</td><td>{{remains|default:"-"}}</td></tr>
{% endfor %}
</table>
</div>
@@ -612,7 +613,7 @@
<table class="table table-striped">
<tr><th>{% trans "Type" %}</th><th>{% trans "Number" %}</th></tr>
{% for label, nb in item.nb_documents_by_types %}
- <tr><td>{{label}}</td><td>{{nb}}</td></tr>
+ <tr><td>{{label}}</td><td class="text-right">{{nb}}</td></tr>
{% endfor %}
</table>
</div>
diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py
index f81933bee..385061c0a 100644
--- a/archaeological_operations/views.py
+++ b/archaeological_operations/views.py
@@ -1094,14 +1094,15 @@ class GenerateStatsOperation(IshtarMixin, LoginRequiredMixin, RedirectView):
"_nb_context_records_by_periods", update=True, expected_type=list
)
self.item._get_or_set_stats("_nb_finds", update=True)
+ self.item._get_or_set_stats("_nb_remains", update=True)
self.item._get_or_set_stats(
- "_nb_finds_by_material_type", update=True, expected_type=list
+ "_nb_finds_by_material_type_full", update=True, expected_type=list
)
self.item._get_or_set_stats(
- "_nb_finds_by_types", update=True, expected_type=list
+ "_nb_finds_by_types_full", update=True, expected_type=list
)
self.item._get_or_set_stats(
- "_nb_finds_by_periods", update=True, expected_type=list
+ "_nb_finds_by_periods_full", update=True, expected_type=list
)
self.item._get_or_set_stats("_nb_documents", update=True)
self.item._get_or_set_stats(