Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add voting timestamp log #1900

Merged
merged 17 commits into from
Jul 24, 2023
300 changes: 298 additions & 2 deletions evap/development/fixtures/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -120069,8 +120069,8 @@
{
"model": "evaluation.userprofile",
"fields": {
"password": "pbkdf2_sha256$150000$VhbGuFyU0NsF$LaOk+e0jHdSnobNBx3Zv9+/jeVxWIJuz2IuLVJVgtNk=",
"last_login": "2020-02-18T13:51:45.323",
"password": "pbkdf2_sha256$600000$8dcuxbY2OgmCEEj3nlUQWG$qk5ic3Er9FrkCd3VUjC1DEfxd76LPVKrzaMEWGSaxyA=",
"last_login": "2023-07-17T21:33:07.189",
"is_superuser": true,
"email": "evap@institution.example.com",
"title": "",
Expand Down Expand Up @@ -131275,6 +131275,302 @@
"html_content": "<i>(English version below)</i><br /><br /><br />\r\n\r\n\r\nHallo {{ user.first_name }},<br /><br />\r\n\r\nes gibt noch nicht überprüfte Textantworten für eine oder mehrere Evaluierungen, bei denen der Evaluierungszeitraum abgelaufen ist und nicht mehr auf Notenveröffentlichungen gewartet werden muss. Bitte überprüfe die Textantworten für diese Evaluierungen möglichst bald:\r\n<ul>{% for evaluation, url in evaluation_url_tuples %}\r\n<li><a href='{{ url }}'>{{ evaluation.full_name_de }}</a></li>\r\n{% endfor %}</ul><br /><br />\r\n\r\n<i>(Dies ist eine automatisch versendete E-Mail.)</i><br /><br />\r\n\r\n<hr><br /><br />\r\n\r\nDear {{ user.first_name }},<br /><br />\r\n\r\nthere are text answers not yet reviewed for one or more evaluations where the evaluation period has ended and there is no need to wait for grade publishing. Please review the text answers for these evaluations as soon as possible:\r\n<ul>{% for evaluation, url in evaluation_url_tuples %}\r\n<li><a href='{{ url }}'>{{ evaluation.full_name_en }}</a></li>\r\n{% endfor %}</ul><br /><br />\r\n\r\n<i>(This is an automated message.)</i>"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 1,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-07T00:19:49"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 2,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-11T01:33:38"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 3,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-23T06:09:16"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 4,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-03T19:27:37"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 5,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-02T00:11:57"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 6,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-29T16:22:45"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 7,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-16T06:15:26"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 8,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-09T13:41:46"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 9,
"fields": {
"evaluation": 347,
"timestamp": "2014-05-29T13:03:12"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 10,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-02T12:24:13"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 11,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-25T19:09:52"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 12,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-11T23:41:20"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 13,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-30T21:17:46"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 14,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-18T06:08:40"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 15,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-03T18:12:06"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 16,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-11T15:03:02"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 17,
"fields": {
"evaluation": 348,
"timestamp": "2014-05-13T05:31:39"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 18,
"fields": {
"evaluation": 1503,
"timestamp": "2014-05-13T19:12:47"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 19,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-05T21:46:10"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 20,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-25T19:28:09"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 21,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-14T03:40:33"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 22,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-11T19:45:23"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 23,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-02T01:32:22"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 24,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-25T00:39:24"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 25,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-28T19:24:29"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 26,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-21T05:43:29"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 27,
"fields": {
"evaluation": 1577,
"timestamp": "2014-05-18T07:03:43"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 28,
"fields": {
"evaluation": 1600,
"timestamp": "2014-05-14T12:47:54"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 29,
"fields": {
"evaluation": 1600,
"timestamp": "2014-05-05T16:04:27"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 30,
"fields": {
"evaluation": 1600,
"timestamp": "2014-05-10T04:58:38"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 31,
"fields": {
"evaluation": 1673,
"timestamp": "2016-07-23T19:19:13"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 32,
"fields": {
"evaluation": 1673,
"timestamp": "2021-05-24T05:33:10"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 33,
"fields": {
"evaluation": 1673,
"timestamp": "2015-10-31T12:39:08"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 34,
"fields": {
"evaluation": 1682,
"timestamp": "2016-09-20T00:45:07"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 35,
"fields": {
"evaluation": 1682,
"timestamp": "2023-07-13T23:17:07"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 36,
"fields": {
"evaluation": 1682,
"timestamp": "2016-04-05T13:11:54"
}
},
{
"model": "evaluation.votetimestamp",
"pk": 37,
"fields": {
"evaluation": 1694,
"timestamp": "2017-11-29T01:40:06"
FSadrieh marked this conversation as resolved.
Show resolved Hide resolved
}
},
{
"model": "rewards.rewardpointredemptionevent",
"pk": 1,
Expand Down
25 changes: 25 additions & 0 deletions evap/evaluation/migrations/0138_votetimestamp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.2.3 on 2023-07-17 20:09

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):
dependencies = [
("evaluation", "0137_use_more_database_constraints"),
]

operations = [
migrations.CreateModel(
name="VoteTimestamp",
fields=[
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("timestamp", models.DateTimeField(default=django.utils.timezone.now, verbose_name="vote timestamp")),
(
"evaluation",
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="evaluation.evaluation"),
),
],
),
]
6 changes: 6 additions & 0 deletions evap/evaluation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.safestring import SafeData
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_fsm import FSMIntegerField, transition
from django_fsm.signals import post_transition
Expand Down Expand Up @@ -2139,3 +2140,8 @@ def send_textanswer_reminder_to_user(cls, user: UserProfile, evaluation_url_tupl
body_params = {"user": user, "evaluation_url_tuples": evaluation_url_tuples}
template = cls.objects.get(name=cls.TEXT_ANSWER_REVIEW_REMINDER)
template.send_to_user(user, {}, body_params, use_cc=False)


class VoteTimestamp(models.Model):
evaluation = models.ForeignKey(Evaluation, models.CASCADE)
timestamp = models.DateTimeField(verbose_name=_("vote timestamp"), default=now)
1 change: 1 addition & 0 deletions evap/staff/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ def __init__(self, data=None, *, instance: Course):
"_participant_count",
"_voter_count",
"voters",
"votetimestamp",
}

CONTRIBUTION_COPIED_FIELDS = {
Expand Down
1 change: 1 addition & 0 deletions evap/staff/templates/staff_semester_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ <h3>
<a class="dropdown-item" href="{% url 'staff:semester_export' semester.id %}">{% trans 'Export results' %}</a>
<a class="dropdown-item" href="{% url 'staff:semester_raw_export' semester.id %}">{% trans 'Export raw evaluation data' %}</a>
<a class="dropdown-item" href="{% url 'staff:semester_participation_export' semester.id %}">{% trans 'Export participation data' %}</a>
<a class="dropdown-item" href="{% url 'staff:vote_timestamps_export' semester.id %}">{% trans 'Export vote timestamps' %}</a>
</div>
</div>
{% if not semester.participations_are_archived %}
Expand Down
Loading