diff --git a/management/forms.py b/management/forms.py index 5b4ffad0ebfaef2139afaf724075e5411e477378..8fd739f85868384959ba86617dcdda4264ff05a6 100644 --- a/management/forms.py +++ b/management/forms.py @@ -44,18 +44,6 @@ class StopElectionForm(forms.ModelForm): return instance -class ChangeElectionPublicStateForm(forms.ModelForm): - class Meta: - model = Election - fields = ['result_published'] - widgets = { - 'result_published': forms.RadioSelect - } - labels = { - 'result_published': '', - } - - class TemplateStringForm: def clean_email_text(self, test_data: List[str], field: str): """ @@ -220,7 +208,7 @@ class AddElectionForm(forms.ModelForm, TemplateStringForm): model = Election fields = ( 'title', 'start_date', 'end_date', 'session', 'max_votes_yes', 'voters_self_apply', 'send_emails_on_start', - 'remind_text', 'disable_abstention') + 'remind_text', 'disable_abstention', 'result_unpublished') labels = { 'title': 'Election Name', @@ -232,6 +220,7 @@ class AddElectionForm(forms.ModelForm, TemplateStringForm): 'disable_abstention': 'Disable the option to abstain in this election<br>' '(only YES and NO votes will be allowed)', 'remind_text': '', + 'result_unpublished': 'Disable auto publish of the election results', } def clean_remind_text(self): diff --git a/management/templates/management/add_election.html b/management/templates/management/add_election.html index 996ff478b119d1d86deb9f603bded80e13b7814a..17873c02ad45da25c5813fd0412eea4e2636c169 100644 --- a/management/templates/management/add_election.html +++ b/management/templates/management/add_election.html @@ -17,7 +17,7 @@ {{ form|as_crispy_errors }} {% for field in form %} - {% if field.html_name != "remind_text" and field.html_name != "send_emails_on_start" and field.html_name != "voters_self_apply" and field.html_name != "email" and field.html_name != 'disable_abstention' %} + {% if field.html_name != "remind_text" and field.html_name != "send_emails_on_start" and field.html_name != "voters_self_apply" and field.html_name != "email" and field.html_name != 'disable_abstention' and field.html_name != 'result_unpublished' %} {{ field|as_crispy_field }} {% endif %} {% endfor %} @@ -32,6 +32,7 @@ </span> </div> <div id="collapseOne" class="card-body collapse{% if form.remind_text.value %} show{% endif %}"> + {{ form.result_unpublished|as_crispy_field }} {{ form.disable_abstention|as_crispy_field }} {{ form.voters_self_apply|as_crispy_field }} {{ form.send_emails_on_start|as_crispy_field }} diff --git a/management/templates/management/election.html b/management/templates/management/election.html index f695a61e8f8f9963a7d19e7dd93e67bc1660a26d..aba5e8ceac651de29089543f9e8b20f05f945a47 100644 --- a/management/templates/management/election.html +++ b/management/templates/management/election.html @@ -67,35 +67,35 @@ </div> {% endif %} </div> - <div class="card shadow mt-4"> - <div class="card-body"> - {% if not election.closed %} - <h4> - {% if election.voters_self_apply %}Applicants{% else %}Options{% endif %} - {% if election.can_apply %} - <a class="btn btn-success float-right" role="button" - href="{% url 'management:add_application' election.pk %}"> - {% if election.voters_self_apply %}Add applicant{% else %}Add option{% endif %} - </a> - {% endif %} - </h4> + <div class="card shadow mt-4"> + <div class="card-body"> + {% if not election.closed %} + <h4> + {% if election.voters_self_apply %}Applicants{% else %}Options{% endif %} + {% if election.can_apply %} + <a class="btn btn-success float-right" role="button" + href="{% url 'management:add_application' election.pk %}"> + {% if election.voters_self_apply %}Add applicant{% else %}Add option{% endif %} + </a> + {% endif %} + </h4> - <hr> - <table class="table table-striped"> - <thead> - <tr> - <th scope="col">#</th> - <th scope="col">{% if election.voters_self_apply %}Applicant{% else %}Option{% endif %}</th> - <th scope="col"></th> - </tr> - </thead> - <tbody> - {% for application in applications %} - <tr> - <th scope="row">{{ forloop.counter }}</th> - <td>{{ application.get_display_name }}</td> - <td> - {% if election.can_apply %} + <hr> + <table class="table table-striped"> + <thead> + <tr> + <th scope="col">#</th> + <th scope="col">{% if election.voters_self_apply %}Applicant{% else %}Option{% endif %}</th> + <th scope="col"></th> + </tr> + </thead> + <tbody> + {% for application in applications %} + <tr> + <th scope="row">{{ forloop.counter }}</th> + <td>{{ application.get_display_name }}</td> + <td> + {% if election.can_apply %} <form action="{% url 'management:delete_application' pk=election.pk application_id=application.pk %}" method="post"> @@ -119,14 +119,15 @@ {% else %} <h4>Result</h4> {% include 'management/results.html' %} - <hr> - <h5>Publish result</h5> - <form action="{% url 'management:election' election.pk %}" method="post"> - {% csrf_token %} - <input type="hidden" name="action" value="publish"> - {{ election_upload_application_form |crispy }} - <button type="submit" class="btn btn-info">Apply</button> - </form> + + {% if election.result_unpublished %} + <hr> + <form action="{% url 'management:election' election.pk %}" method="post"> + {% csrf_token %} + <input type="hidden" name="action" value="publish"> + <button type="submit" class="btn btn-info">Publish Results</button> + </form> + {% endif %} <hr> <a href="{% url 'management:export_csv' election.pk %}" class="btn btn-primary mr-2">Export result as CSV</a> diff --git a/management/views.py b/management/views.py index 98f4e9105cc031d01c9096b2e88ecc514ad82141..d2592d611e9f6017adfa1c56c8aeb119cb9ba223 100644 --- a/management/views.py +++ b/management/views.py @@ -29,7 +29,6 @@ from management.forms import ( AddVotersForm, ApplicationUploadForm, StopElectionForm, - ChangeElectionPublicStateForm, AddTokensForm, CSVUploaderForm, SessionSettingsForm @@ -95,8 +94,8 @@ def session_detail(request, pk=None): existing_elections = bool(elections) open_elections = [e for e in elections if e.is_open] upcoming_elections = [e for e in elections if not e.started] - published_elections = [e for e in elections if e.closed and int(e.result_published)] - closed_elections = [e for e in elections if e.closed and not int(e.result_published)] + published_elections = [e for e in elections if e.closed and not e.result_unpublished] + closed_elections = [e for e in elections if e.closed and e.result_unpublished] context = { 'session': session, 'existing_elections': existing_elections, @@ -229,7 +228,6 @@ def election_detail(request, pk): 'applications': election.applications.all(), 'stop_election_form': StopElectionForm(instance=election), 'start_election_form': StartElectionForm(instance=election), - 'election_upload_application_form': ChangeElectionPublicStateForm(instance=election) } if request.POST and request.POST.get('action') == 'close' and election.is_open: @@ -250,10 +248,8 @@ def election_detail(request, pk): context['start_election_form'] = form if request.POST and request.POST.get('action') == 'publish': - form = ChangeElectionPublicStateForm(instance=election, data=request.POST) - if form.is_valid(): - form.save() - context['election_upload_application_form'] = form + election.result_unpublished = False + election.save() return render(request, template_name='management/election.html', context=context) diff --git a/vote/migrations/0027_change_field_type_results_published.py b/vote/migrations/0027_change_field_type_results_published.py new file mode 100644 index 0000000000000000000000000000000000000000..2d38c2eaef8e8aa954b59a385b81c48fc2120a19 --- /dev/null +++ b/vote/migrations/0027_change_field_type_results_published.py @@ -0,0 +1,36 @@ +# Generated by Django 3.1.4 on 2021-06-18 13:47 + +from django.db import migrations, models + + +def char2bool(apps, schema_editor): + election = apps.get_model('vote', 'election') + for row in election.objects.all(): + row.result_unpublished = not bool(int(row.result_published)) + row.save(update_fields=['result_unpublished']) + + +def bool2char(apps, schema_editor): + election = apps.get_model('vote', 'election') + for row in election.objects.all(): + row.result_published = str(int(not row.result_unpublished)) + row.save(update_fields=['result_published']) + + +class Migration(migrations.Migration): + dependencies = [ + ('vote', '0026_voter_invalid_email'), + ] + + operations = [ + migrations.AddField( + model_name='election', + name='result_unpublished', + field=models.BooleanField(default=True), + ), + migrations.RunPython(char2bool, reverse_code=bool2char), + migrations.RemoveField( + model_name='election', + name='result_published' + ) + ] diff --git a/vote/models.py b/vote/models.py index 85151aad8e46d310727ef071ae85f5e83fb69cb3..9730ae32f1a75f529727e35e698a4df1e703d9f3 100644 --- a/vote/models.py +++ b/vote/models.py @@ -97,8 +97,7 @@ class Election(models.Model): end_date = models.DateTimeField(blank=True, null=True) max_votes_yes = models.IntegerField(blank=True, null=True) session = models.ForeignKey(Session, related_name='elections', on_delete=CASCADE) - result_published = models.CharField(max_length=1, choices=[('0', 'unpublished'), ('1', 'published')], - default='0') + result_unpublished = models.BooleanField(null=False, default=True) disable_abstention = models.BooleanField(default=False) voters_self_apply = models.BooleanField(default=False) send_emails_on_start = models.BooleanField(default=False) diff --git a/vote/templates/vote/index_election_item.html b/vote/templates/vote/index_election_item.html index 442113ab1b82247ada2d71caf77daf010dc13251..6413fa3d6d54ed60209680b06d79add496f5786d 100644 --- a/vote/templates/vote/index_election_item.html +++ b/vote/templates/vote/index_election_item.html @@ -24,7 +24,7 @@ <div class="list-group mt-3"> {% if can_vote %} <a class="btn btn-primary" role="button" href="{% url 'vote:vote' election.pk %}">Vote Now!</a> - {% elif election.closed and election.result_published == '1' %} + {% elif election.closed and not election.result_unpublished %} <div class="alert alert-info" role="alert"> <h4 class="alert-heading">Voting Ended:</h4> <hr> diff --git a/vote/templates/vote/spectator_election_item.html b/vote/templates/vote/spectator_election_item.html index 1559961fe0dd5bdf49094ec836fe4febeaff31f6..ce68ec184c4ebe7c066fa5a6349372c4ae05aeb1 100644 --- a/vote/templates/vote/spectator_election_item.html +++ b/vote/templates/vote/spectator_election_item.html @@ -10,7 +10,7 @@ {% endif %} <hr> <div class="list-group mt-3"> - {% if election.closed and election.result_published == '1' %} + {% if election.closed and not election.result_unpublished %} <div class="alert alert-info" role="alert"> <h4 class="alert-heading">Election result:</h4> <hr> diff --git a/vote/views.py b/vote/views.py index dd68fcd040015c69b0f4003fb2ad7a0a51a28f2b..04bc74d6604c7d1d9bd4b1c4bced1b6cd0ecbc1a 100644 --- a/vote/views.py +++ b/vote/views.py @@ -73,8 +73,8 @@ def index(request): open_elections = sorted([e for e in elections if e[0].is_open], key=date_desc) upcoming_elections = sorted([e for e in elections if not e[0].started], key=date_asc) - published_elections = sorted([e for e in elections if e[0].closed and int(e[0].result_published)], key=date_desc) - closed_elections = sorted([e for e in elections if e[0].closed and not int(e[0].result_published)], key=date_desc) + published_elections = sorted([e for e in elections if e[0].closed and not e[0].result_unpublished], key=date_desc) + closed_elections = sorted([e for e in elections if e[0].closed and e[0].result_unpublished], key=date_desc) context = { 'title': voter.session.title, 'meeting_link': voter.session.meeting_link,