diff --git a/comptages/core/utils.py b/comptages/core/utils.py index 8f9b6ea8..c3957145 100644 --- a/comptages/core/utils.py +++ b/comptages/core/utils.py @@ -1,6 +1,8 @@ +from operator import itemgetter import os from datetime import datetime +from typing import Any from qgis.core import Qgis from qgis.PyQt.uic import loadUiType @@ -65,3 +67,18 @@ def connect_to_db(): db.open() return db + + +def partial_order_with_blanks( + container: dict[int, Any], default_missing=None +) -> dict[int, Any]: + container_copy = container.copy() + blanks = [] + prev = 0 + for k in container_copy: + if k > prev + 1: + blanks.append(k - 1) + prev = k + for b in blanks: + container_copy[b] = default_missing + return dict(sorted(container_copy.items(), key=itemgetter(0))) diff --git a/comptages/report/yearly_report_bike.py b/comptages/report/yearly_report_bike.py index 419b207b..8edcf51c 100644 --- a/comptages/report/yearly_report_bike.py +++ b/comptages/report/yearly_report_bike.py @@ -1,7 +1,6 @@ import os - -from django.db.models import Sum, Count +from django.db.models import Sum, Count, F from django.db.models.functions import Cast from django.db.models.fields import DateField from django.db.models.functions import ( @@ -13,6 +12,7 @@ from openpyxl import load_workbook from comptages.core import definitions +from comptages.core.utils import partial_order_with_blanks from comptages.datamodel.models import CountDetail, Section, Lane @@ -153,13 +153,14 @@ def values_by_class(self): import_status=definitions.IMPORT_STATUS_DEFINITIVE, ) - result = ( + return ( qs.annotate(res=Sum("times")) .values("res") .values("id_category__code") .annotate(tjm=Count("id_category__code")) + .annotate(code=F("id_category__code")) + .order_by("code") ) - return result def tjm_direction_bike(self, categories, direction, weekdays=[0, 1, 2, 3, 4, 5, 6]): qs = CountDetail.objects.filter( @@ -384,10 +385,18 @@ def run(self): row_offset = 4 column_offset = 2 - data = self.values_by_class() row = row_offset - for i in data: - ws.cell(row=row, column=column_offset, value=i["tjm"]) + data = self.values_by_class() + # construct dict by class id and + data = {i["code"]: i for i in data} + # ensure all 6 rows / class ids are there, whether filled with data or with a blank + data = partial_order_with_blanks(data) + for value in data.values(): + ws.cell( + row=row, + column=column_offset, + value=value["tjm"] if value is not None else "", + ) row += 1 ws = workbook["AN_GR"]