diff --git a/ceuk-marking/urls.py b/ceuk-marking/urls.py index 14ffd942..6d3066de 100644 --- a/ceuk-marking/urls.py +++ b/ceuk-marking/urls.py @@ -190,6 +190,21 @@ stats.DuplicateResponsesView.as_view(), name="duplicate_responses", ), + path( + "stats/response_history/", + stats.CouncilHistoryListView.as_view(), + name="select_council_for_history", + ), + path( + "stats/response_history//", + stats.CouncilQuestionHistoryListView.as_view(), + name="question_history_list", + ), + path( + "stats/response_history////", + stats.ResponseHistoryView.as_view(), + name="question_history", + ), # audit screens path( "section/audit//authorities/", diff --git a/crowdsourcer/templates/crowdsourcer/response_history.html b/crowdsourcer/templates/crowdsourcer/response_history.html new file mode 100644 index 00000000..eec3efc4 --- /dev/null +++ b/crowdsourcer/templates/crowdsourcer/response_history.html @@ -0,0 +1,68 @@ +{% extends 'crowdsourcer/base.html' %} + +{% load crowdsourcer_tags %} + +{% block content %} +{% if show_login %} +

Sign in

+Sign in +{% else %} +

Reponse History

+ +{% if missing_question %} +

+ Could not find that question +

+{% else %} +

{{ question.section.title }}: {{ question }}

+ {% if responses is None %} +

+ No responses to that question so far. +

+ {% else %} + + + + + + + + + + + + + {% for response in responses %} + + + + + + + + + {% endfor %} + +
DateUserResponseNotesLinksPrivate notes
+ {{ response.history_date }} + + {{ response.user }} + + {% if response.multi_option %} + {% for r in response.multi_option %} + {{ r }}, + {% endfor %} + {% else %} + {{ response.option }} + {% endif %} + + {{ response.evidence }} + + {{ response.public_notes }} + + {{ response.private_notes }} +
+ {% endif %} +{% endif %} +{% endif %} +{% endblock %} diff --git a/crowdsourcer/templates/crowdsourcer/response_history_authorities.html b/crowdsourcer/templates/crowdsourcer/response_history_authorities.html new file mode 100644 index 00000000..268ec716 --- /dev/null +++ b/crowdsourcer/templates/crowdsourcer/response_history_authorities.html @@ -0,0 +1,29 @@ +{% extends 'crowdsourcer/base.html' %} + +{% load crowdsourcer_tags %} + +{% block content %} +{% if show_login %} +

Sign in

+ Sign in +{% else %} +

{{ session.entity_name }} History

+

+ Click on an authority to see the list of questions for that authority. +

+ + + + {% for authority in authorities %} + + + + {% endfor %} + +
+ + {{ authority.name }} + +
+{% endif %} +{% endblock %} diff --git a/crowdsourcer/templates/crowdsourcer/response_history_questions.html b/crowdsourcer/templates/crowdsourcer/response_history_questions.html new file mode 100644 index 00000000..587ea318 --- /dev/null +++ b/crowdsourcer/templates/crowdsourcer/response_history_questions.html @@ -0,0 +1,51 @@ +{% extends 'crowdsourcer/base.html' %} + +{% load crowdsourcer_tags %} + +{% block content %} +{% if show_login %} +

Sign in

+ Sign in +{% else %} +

Question Data

+ + + + + + + + + + {% for section, data in sections.items %} + + + + + {% for q in data %} + + + + + + + {% endfor %} + + {% endfor %} +
QuestionFirst MarkRight of ReplyAudit
{{ section }}
+ {{ q.number_and_part }} - {{ q.description }} + + + View + + + + View + + + + View + +
+{% endif %} +{% endblock %} diff --git a/crowdsourcer/templates/crowdsourcer/stats.html b/crowdsourcer/templates/crowdsourcer/stats.html index 6ab3f8bb..0508e2c9 100644 --- a/crowdsourcer/templates/crowdsourcer/stats.html +++ b/crowdsourcer/templates/crowdsourcer/stats.html @@ -50,6 +50,9 @@

{{ page_title }}

All answer data {% include 'crowdsourcer/includes/csv-badge.html' %} + + Question response history + {% endif %} {% endblock %} diff --git a/crowdsourcer/views/stats.py b/crowdsourcer/views/stats.py index 915bf15c..2ac29540 100644 --- a/crowdsourcer/views/stats.py +++ b/crowdsourcer/views/stats.py @@ -677,3 +677,77 @@ def get_context_data(self, **kwargs): context["dupes"] = dupes return context + + +class CouncilHistoryListView(StatsUserTestMixin, ListView): + context_object_name = "authorities" + template_name = "crowdsourcer/response_history_authorities.html" + + def get_queryset(self): + return PublicAuthority.objects.filter( + marking_session=self.request.current_session + ).order_by("name") + + +class CouncilQuestionHistoryListView(SelectQuestionView): + template_name = "crowdsourcer/response_history_questions.html" + + def get_queryset(self): + try: + authority = PublicAuthority.objects.get(name=self.kwargs["authority"]) + except PublicAuthority.DoesNotExist: + return None + + return ( + Question.objects.filter( + questiongroup=authority.questiongroup, + section__marking_session=self.request.current_session, + ) + .select_related("section") + .order_by("section__title", "number", "number_part") + ) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + try: + authority = PublicAuthority.objects.get(name=self.kwargs["authority"]) + context["authority"] = authority + except PublicAuthority.DoesNotExist: + context["no_authority"] = True + + return context + + +class ResponseHistoryView(StatsUserTestMixin, ListView): + context_object_name = "responses" + template_name = "crowdsourcer/response_history.html" + + def get_queryset(self): + stage = self.kwargs["stage"] + authority = self.kwargs["authority"] + question = self.kwargs["question"] + + try: + response = Response.objects.get( + question__section__marking_session=self.request.current_session, + question_id=question, + authority__name=authority, + response_type__type=stage, + ) + except Response.DoesNotExist: + return None + return response.history.all() + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + try: + context["question"] = Question.objects.get( + section__marking_session=self.request.current_session, + id=self.kwargs["question"], + ) + except Question.DoesNotExist: + context["missing_question"] = True + + return context