diff options
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 |
commit | 4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9 (patch) | |
tree | 3eda90e6536090906547e93024d79c9c55c2f571 | |
parent | 447c972cf4f9f99c02434b96097d0e914d96056c (diff) | |
download | Ishtar-4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9.tar.bz2 Ishtar-4b9b29bb5b62df6e9982fed5c9e14dd9b68174b9.zip |
✨ sheet operation: find statistics with number of remains
-rw-r--r-- | archaeological_operations/models.py | 73 | ||||
-rw-r--r-- | archaeological_operations/templates/ishtar/sheet_operation.html | 39 | ||||
-rw-r--r-- | 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 %}<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( |