From 79c5103dbed91efbe543b581600b662420e29e10 Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Thu, 23 Aug 2018 10:21:02 +0100
Subject: [PATCH] Tidy up the ordering on the homepage for the apply site

---
 opentech/apply/funds/models/applications.py   | 32 +++++++++++++++----
 opentech/apply/home/models.py                 |  8 +++++
 .../templates/apply_home/apply_home_page.html |  7 ++--
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/opentech/apply/funds/models/applications.py b/opentech/apply/funds/models/applications.py
index e9aa7fe05..c6ce50029 100644
--- a/opentech/apply/funds/models/applications.py
+++ b/opentech/apply/funds/models/applications.py
@@ -3,7 +3,7 @@ from datetime import date
 from django.conf import settings
 from django.core.exceptions import ValidationError
 from django.db import models
-from django.db.models import Q
+from django.db.models import OuterRef, Q, Subquery
 from django.http import Http404
 from django.utils.text import mark_safe
 
@@ -16,6 +16,7 @@ from wagtail.admin.edit_handlers import (
     ObjectList,
     TabbedInterface,
 )
+from wagtail.core.models import PageManager, PageQuerySet
 
 from ..admin_forms import WorkflowFormAdminForm
 from ..edit_handlers import ReadOnlyPanel, ReadOnlyInlinePanel
@@ -24,6 +25,15 @@ from .submissions import ApplicationSubmission
 from .utils import admin_url, EmailForm, SubmittableStreamForm, WorkflowStreamForm, LIMIT_TO_REVIEWERS, LIMIT_TO_STAFF
 
 
+class ApplicationBaseManager(PageQuerySet):
+    def order_by_end_date(self):
+        # OutRef path__startswith with find all descendants of the parent
+        # We only have children, so no issues at this time
+        rounds = RoundBase.objects.open().filter(path__startswith=OuterRef('path'))
+        qs = self.public().live().annotate(end_date=Subquery(rounds.values('end_date')[:1]))
+        return qs.order_by('end_date')
+
+
 class ApplicationBase(EmailForm, WorkflowStreamForm):  # type: ignore
     is_createable = False
 
@@ -37,6 +47,8 @@ class ApplicationBase(EmailForm, WorkflowStreamForm):  # type: ignore
         blank=True,
     )
 
+    objects = PageManager.from_queryset(ApplicationBaseManager)()
+
     parent_page_types = ['apply_home.ApplyHomePage']
 
     def detail(self):
@@ -45,11 +57,7 @@ class ApplicationBase(EmailForm, WorkflowStreamForm):  # type: ignore
 
     @property
     def open_round(self):
-        rounds = RoundBase.objects.child_of(self).live().public().specific()
-        return rounds.filter(
-            Q(start_date__lte=date.today()) &
-            Q(Q(end_date__isnull=True) | Q(end_date__gte=date.today()))
-        ).first()
+        return RoundBase.objects.child_of(self).open().first()
 
     def next_deadline(self):
         try:
@@ -77,10 +85,22 @@ class ApplicationBase(EmailForm, WorkflowStreamForm):  # type: ignore
     ])
 
 
+class RoundBaseManager(PageQuerySet):
+    def open(self):
+        rounds = self.live().public().specific()
+        rounds = rounds.filter(
+            Q(start_date__lte=date.today()) &
+            Q(Q(end_date__isnull=True) | Q(end_date__gte=date.today()))
+        )
+        return rounds
+
+
 class RoundBase(WorkflowStreamForm, SubmittableStreamForm):  # type: ignore
     is_creatable = False
     submission_class = ApplicationSubmission
 
+    objects = PageManager.from_queryset(RoundBaseManager)()
+
     subpage_types = []  # type: ignore
 
     lead = models.ForeignKey(
diff --git a/opentech/apply/home/models.py b/opentech/apply/home/models.py
index cc25885c0..3d135ce17 100644
--- a/opentech/apply/home/models.py
+++ b/opentech/apply/home/models.py
@@ -4,6 +4,8 @@ from wagtail.search import index
 
 from django.db import models
 
+from opentech.apply.funds.models import ApplicationBase, LabBase
+
 
 class ApplyHomePage(Page):
     # Only allow creating HomePages at the root level
@@ -19,3 +21,9 @@ class ApplyHomePage(Page):
     content_panels = Page.content_panels + [
         FieldPanel('strapline'),
     ]
+
+    def get_context(self, *args, **kwargs):
+        context = super().get_context(*args, **kwargs)
+        context['open_funds'] = ApplicationBase.objects.order_by_end_date()
+        context['open_labs'] = LabBase.objects.public().live()
+        return context
diff --git a/opentech/apply/home/templates/apply_home/apply_home_page.html b/opentech/apply/home/templates/apply_home/apply_home_page.html
index 861377a97..041adf22b 100644
--- a/opentech/apply/home/templates/apply_home/apply_home_page.html
+++ b/opentech/apply/home/templates/apply_home/apply_home_page.html
@@ -16,8 +16,11 @@
     </div>
 
     <div class="wrapper wrapper--listings">
-    {% for child_page in page.get_children.public.live %}
-        {% include "apply_home/includes/apply_listing.html" with page=child_page.specific %}
+    {% for fund in open_funds %}
+        {% include "apply_home/includes/apply_listing.html" with page=fund.specific %}
+    {% endfor %}
+    {% for lab in open_labs %}
+        {% include "apply_home/includes/apply_listing.html" with page=lab.specific %}
     {% endfor %}
     </div>
 
-- 
GitLab