From c09eb96afdf647efe1845f7e6d8d44a6085f64f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Krienb=C3=BChl?= Date: Fri, 28 Aug 2015 14:25:40 +0200 Subject: [PATCH] The allocation availability calculation is now faster and accurate --- HISTORY.rst | 3 +++ onegov/town/utils.py | 6 +++--- onegov/town/views/allocation.py | 29 +++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index deed9b8..28f4343 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,9 @@ Changelog Unreleased ~~~~~~~~~~ +- The allocation availability calculation is now faster and accurate. + [href] + - Expired reservation sessions are now automatically removed. [href] diff --git a/onegov/town/utils.py b/onegov/town/utils.py index 4b31675..b227304 100644 --- a/onegov/town/utils.py +++ b/onegov/town/utils.py @@ -79,9 +79,9 @@ class AllocationEventInfo(object): __slots__ = ['allocation', 'availability', 'request', 'translate'] - def __init__(self, allocation, request): + def __init__(self, allocation, availability, request): self.allocation = allocation - self.availability = allocation.availability + self.availability = availability self.request = request self.translate = request.translate @@ -118,7 +118,7 @@ def event_title(self): })) else: quota = self.allocation.quota - quota_left = self.allocation.quota_left + quota_left = int(quota * self.availability / 100) if quota == 1: if quota_left: diff --git a/onegov/town/views/allocation.py b/onegov/town/views/allocation.py index 98a1ca2..a68f43d 100644 --- a/onegov/town/views/allocation.py +++ b/onegov/town/views/allocation.py @@ -1,7 +1,9 @@ import morepath +from itertools import groupby from libres.db.models import Allocation from libres.modules.errors import LibresError +from operator import attrgetter from onegov.core.security import Public, Private from onegov.libres import Resource, ResourceCollection from onegov.town import TownApp, _, utils @@ -30,13 +32,32 @@ def view_allocations_json(self, request): return [] scheduler = self.get_scheduler(request.app.libres_context) + queries = scheduler.queries - query = scheduler.allocations_in_range(start, end) + # get all allocations (including mirrors), for the availability calculation + query = scheduler.allocations_in_range(start, end, masters_only=False) query = query.order_by(Allocation._start) - return [ - utils.AllocationEventInfo(a, request).as_dict() for a in query.all() - ] + allocations = query.all() + + # put only return the master allocations + events = [] + + for key, group in groupby(allocations, key=attrgetter('_start')): + grouped = tuple(group) + availability = queries.availability_by_allocations(grouped) + + for allocation in grouped: + if allocation.is_master: + events.append( + utils.AllocationEventInfo( + allocation, + availability, + request + ) + ) + + return [e.as_dict() for e in events] def get_new_allocation_form_class(resource, request):