From 4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 26 Sep 2025 16:38:26 +0200 Subject: ✨ sheet operation: find statistics with number of remains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- archaeological_operations/models.py | 73 ++++++++++++++-------- .../templates/ishtar/sheet_operation.html | 39 ++++++------ archaeological_operations/views.py | 7 ++- 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 %}{% trans "Operation" %} - {{item.short_label}}{% if item.common_name %} - {{item.common_name}}{% endif %}{% endblock %} @@ -535,12 +535,12 @@

{% trans "Parcels" %}

- {% field_flex_2 "Number of parcels" item.nb_parcels %} + {% field_flex_2 "Number of parcels" item.nb_parcels|intcomma %}

{% trans "Context records" %}

- {% field_flex_2 "Number of context records" item.nb_context_records %} + {% field_flex_2 "Number of context records" item.nb_context_records|intcomma %}
{% if item.nb_context_records_by_type %} @@ -548,7 +548,7 @@ {% for label, nb in item.nb_context_records_by_type %} - + {% endfor %}
{% trans "Type" %}{% trans "Number" %}
{{label|default:"-"}}{{nb}}
{{label|default:"-"}}{{nb}}
@@ -558,7 +558,7 @@ {% for label, nb in item.nb_context_records_by_periods %} - + {% endfor %}
{% trans "Chronological period" %}{% trans "Number" %}
{{label|default:"-"}}{{nb}}
{{label|default:"-"}}{{nb}}
@@ -567,35 +567,36 @@

{% trans "Finds" %}

- {% 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 %}
- {% if item.nb_finds_by_material_type %} + {% if item.nb_finds_by_material_type_full %}
- - {% for label, nb in item.nb_finds_by_material_type %} - + + {% for label, nb, remains in item.nb_finds_by_material_type_full %} + {% endfor %}
{% trans "Material type" %}{% trans "Number" %}
{{label|default:"-"}}{{nb}}
{% trans "Material type" %}{% trans "Number" %}{% trans "Number of remains" %}
{{label|default:"-"}}{{nb}}{{remains|default:"-"}}
{% endif %} - {% if item.nb_finds_by_types %} + {% if item.nb_finds_by_types_full %}
- - {% for label, nb in item.nb_finds_by_types %} - + + {% for label, nb, remains in item.nb_finds_by_types_full %} + {% endfor %}
{% trans "Object type" %}{% trans "Number" %}
{{label}}{{nb}}
{% trans "Object type" %}{% trans "Number" %}{% trans "Number of remains" %}
{{label}}{{nb}}{{remains|default:"-"}}
{% endif %} - {% if item.nb_finds_by_periods %} + {% if item.nb_finds_by_periods_full %}
- - {% for label, nb in item.nb_finds_by_periods %} - + + {% for label, nb, remains in item.nb_finds_by_periods_full %} + {% endfor %}
{% trans "Chronological period" %}{% trans "Number" %}
{{label|default:"-"}}{{nb}}
{% trans "Chronological period" %}{% trans "Number" %}{% trans "Number of remains" %}
{{label|default:"-"}}{{nb}}{{remains|default:"-"}}
@@ -612,7 +613,7 @@ {% for label, nb in item.nb_documents_by_types %} - + {% endfor %}
{% trans "Type" %}{% trans "Number" %}
{{label}}{{nb}}
{{label}}{{nb}}
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( -- cgit v1.2.3