From 891ac2585d85c868b38a3d7cb646ef9aed5e349d Mon Sep 17 00:00:00 2001
From: Ole Laursen <olau@iola.dk>
Date: Wed, 2 May 2012 17:47:40 +0000
Subject: [PATCH] Use revision numbers to identify ballots and put a warning on
 closed ballots.  - Legacy-Id: 4352

---
 ietf/doc/utils.py                             | 22 ++++++++++
 ietf/idrfc/views_doc.py                       | 44 +++++++++----------
 .../idrfc/document_ballot_content.html        |  8 +++-
 3 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py
index a75ea5a4f..dd1ff2893 100644
--- a/ietf/doc/utils.py
+++ b/ietf/doc/utils.py
@@ -121,6 +121,28 @@ def get_chartering_type(doc):
 
     return chartering
 
+def augment_events_with_revision(doc, events):
+    """Take a set of events for doc and add a .rev attribute with the
+    revision they refer to by checking NewRevisionDocEvents."""
+
+    event_revisions = list(NewRevisionDocEvent.objects.filter(doc=doc).order_by('time', 'id').values('id', 'rev', 'time'))
+
+    cur_rev = doc.rev
+    if doc.get_state_slug() == "rfc":
+        cur_rev = "RFC"
+
+    for e in sorted(events, key=lambda e: (e.time, e.id), reverse=True):
+        while event_revisions and (e.time, e.id) < (event_revisions[-1]["time"], event_revisions[-1]["id"]):
+            event_revisions.pop()
+
+        if event_revisions:
+            cur_rev = event_revisions[-1]["rev"]
+        else:
+            cur_rev = "00"
+
+        e.rev = cur_rev
+
+
 def augment_with_telechat_date(docs):
     """Add a telechat_date attribute to each document with the
     scheduled telechat or None if it's not scheduled."""
diff --git a/ietf/idrfc/views_doc.py b/ietf/idrfc/views_doc.py
index ac6035302..b95c1d416 100644
--- a/ietf/idrfc/views_doc.py
+++ b/ietf/idrfc/views_doc.py
@@ -50,7 +50,7 @@ from ietf.idrfc.models import RfcIndex, DraftVersions
 from ietf.idrfc.idrfc_wrapper import BallotWrapper, IdWrapper, RfcWrapper
 from ietf.ietfworkflows.utils import get_full_info_for_draft
 from ietf.doc.models import *
-from ietf.doc.utils import get_chartering_type, needed_ballot_positions, active_ballot_positions
+from ietf.doc.utils import *
 from ietf.utils.history import find_history_active_at
 from ietf.ietfauth.decorators import has_role
 
@@ -190,23 +190,7 @@ def document_history(request, name):
     # grab event history
     events = doc.docevent_set.all().order_by("-time", "-id").select_related("by")
 
-    # fill in revision numbers
-    event_revisions = list(NewRevisionDocEvent.objects.filter(doc=doc).order_by('time', 'id').values('rev', 'time'))
-
-    cur_rev = doc.rev
-    if doc.get_state_slug() == "rfc":
-        cur_rev = "RFC"
-
-    for e in events:
-        while event_revisions and e.time < event_revisions[-1]["time"]:
-            event_revisions.pop()
-
-        if event_revisions:
-            cur_rev = event_revisions[-1]["rev"]
-        else:
-            cur_rev = "00"
-
-        e.rev = cur_rev
+    augment_events_with_revision(doc, events)
 
     return render_to_response("idrfc/document_history.html",
                               dict(doc=doc,
@@ -255,13 +239,21 @@ def document_writeup(request, name):
 
 def document_ballot_content(request, doc, ballot_id, editable=True):
     """Render HTML string with content of ballot page."""
+    all_ballots = list(BallotDocEvent.objects.filter(doc=doc, type="created_ballot").order_by("time"))
+    augment_events_with_revision(doc, all_ballots)
+
+    ballot = None
     if ballot_id != None:
-        ballot = doc.latest_event(BallotDocEvent, type="created_ballot", pk=ballot_id)
-    else:
-        ballot = doc.latest_event(BallotDocEvent, type="created_ballot")
+        ballot_id = int(ballot_id)
+        for b in all_ballots:
+            if b.id == ballot_id:
+                ballot = b
+                break
+    elif all_ballots:
+        ballot = all_ballots[-1]
 
     if not ballot:
-        raise Http404()
+        raise Http404
 
     deferred = None
     if doc.type_id == "draft" and doc.get_state_slug("draft-iesg") == "defer":
@@ -314,7 +306,12 @@ def document_ballot_content(request, doc, ballot_id, editable=True):
     text_positions = [p for p in positions if p.discuss or p.comment]
     text_positions.sort(key=lambda p: (p.old_ad, p.ad.plain_name()))
 
-    all_ballots = BallotDocEvent.objects.filter(doc=doc, type="created_ballot")
+    ballot_open = not BallotDocEvent.objects.filter(doc=doc,
+                                                    type__in=("closed_ballot", "created_ballot"),
+                                                    time__gt=ballot.time,
+                                                    ballot_type=ballot.ballot_type)
+    if not ballot_open:
+        editable = False
 
     return render_to_string("idrfc/document_ballot_content.html",
                               dict(doc=doc,
@@ -322,6 +319,7 @@ def document_ballot_content(request, doc, ballot_id, editable=True):
                                    position_groups=position_groups,
                                    text_positions=text_positions,
                                    editable=editable,
+                                   ballot_open=ballot_open,
                                    deferred=deferred,
                                    summary=summary,
                                    all_ballots=all_ballots,
diff --git a/ietf/templates/idrfc/document_ballot_content.html b/ietf/templates/idrfc/document_ballot_content.html
index 673cafa8c..d30d6ef3a 100644
--- a/ietf/templates/idrfc/document_ballot_content.html
+++ b/ietf/templates/idrfc/document_ballot_content.html
@@ -39,15 +39,19 @@
 
 {% if all_ballots and all_ballots|length > 1 %}
 <div class="other-ballots">
-  Other ballots:
+  Available ballots:
 {% for b in all_ballots %}
-<a{% if b != ballot %} href="{% url doc_ballot name=doc.name,ballot_id=b.pk %}"{% endif %}>{{ b.ballot_type.name }} ({{ b.time|date:"Y-m-d" }})</a>
+<a{% if b != ballot %} href="{% url doc_ballot name=doc.name,ballot_id=b.pk %}"{% endif %}>{{ b.ballot_type.name }} ({{ b.rev }})</a>
 {% endfor %}
 </div>
 {% endif %}
 
 <h2 style="margin-top:12px;">{{ ballot.ballot_type.question }}</h2>
 
+{% if not ballot_open %}
+<p>Note: This ballot was opened for revision {{ ballot.rev }} and is now closed.</p>
+{% endif %}
+
 <p>Summary: <i>{{ summary }}</i></p>
 
 {% for p in text_positions %}