Skip to content

Commit

Permalink
Merge pull request #2071 from DemocracyClub/col20241028
Browse files Browse the repository at this point in the history
Show different registration info for City of London Council ballots
  • Loading branch information
chris48s authored Nov 4, 2024
2 parents 23a3454 + 742b2a0 commit 36d9c34
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 151 deletions.
197 changes: 105 additions & 92 deletions locale/cy/LC_MESSAGES/django.po

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ djangorestframework-jsonp==1.0.2
feedparser==6.0.10

sentry-sdk==1.27.1
uk-election-timetables==3.0.0
uk-election-timetables==4.0.0
uk-election-ids==0.8.0
django-dotenv==1.4.2
akismet==24.5.1
29 changes: 19 additions & 10 deletions wcivf/apps/elections/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,30 +457,39 @@ def expected_sopn_date(self):
return get_election_timetable(
self.ballot_paper_id, self.post.territory
).sopn_publish_date

except AttributeError:
return None

@property
def registration_deadline(self):
date = get_election_timetable(
self.ballot_paper_id, self.post.territory
).registration_deadline
try:
date = get_election_timetable(
self.ballot_paper_id, self.post.territory
).registration_deadline
except AttributeError:
return None

return date.strftime("%d %B %Y")

@property
def past_registration_deadline(self):
registration_deadline = get_election_timetable(
self.ballot_paper_id, self.post.territory
).registration_deadline
try:
registration_deadline = get_election_timetable(
self.ballot_paper_id, self.post.territory
).registration_deadline
except AttributeError:
return None

return registration_deadline < datetime.date.today()

@property
def postal_vote_application_deadline(self):
return get_election_timetable(
self.ballot_paper_id, self.post.territory
).postal_vote_application_deadline
try:
return get_election_timetable(
self.ballot_paper_id, self.post.territory
).postal_vote_application_deadline
except AttributeError:
return None

@property
def postal_vote_requires_form(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{% load i18n %}

<details open>
<summary>
<h2>
<span aria-hidden="true"></span>
{% blocktrans trimmed %}Register to vote{% endblocktrans %}
</h2>
</summary>
<p>
{% blocktrans trimmed %}
City of London council elections do not use the same electoral register as other elections.
{% endblocktrans %}
</p>
<p>
{% blocktrans trimmed %}
Both residents and city workers are eligible to vote. There is one register
published annually, and the deadline to apply is 30 November each year.
The new register comes into force on 16 February each year,
and cannot be modified after that date. For more information, visit the
<a href="https://www.speakforthecity.com/">Speak for the City</a>
website or contact City of London electoral services.
{% endblocktrans %}
</p>
{% if council.council_id %}
<p>
{% blocktrans trimmed %}
For questions about your poll card, polling place, or about returning your postal voting ballot, contact your council.
{% endblocktrans %}
</p>
{% if registration %}
{% include "elections/includes/_council_contact_details.html" with contact_details=registration %}
{% endif %}
{% if council %}
{% include "elections/includes/_council_contact_details.html" with contact_details=council %}
{% endif %}
{% endif %}
</details>
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ <h2 id='register'>
</a>
{% endblocktrans %}
</p>
{% if postelection %}
<p>
{% blocktrans trimmed with registration_deadline=postelection.registration_deadline|naturalday:"j F Y" election_date=postelection.election.election_date|naturalday:"j F Y" %}
Register before midnight on {{ registration_deadline }} to vote on {{ election_date }}.
{% endblocktrans %}
</p>
{% endif %}
<p>
{% blocktrans trimmed with registration_deadline=card.registration_deadline|naturalday:"j F Y" election_date=card.election_date|naturalday:"j F Y" %}
Register before midnight on {{ registration_deadline }} to vote on {{ election_date }}.
{% endblocktrans %}
</p>
{% if council.council_id %}
<p>
{% blocktrans trimmed %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,28 @@ <h3>{% if postelection.is_london_assembly_additional %}{% trans "Additional memb
{% if object.election.slug == "europarl.2019-05-23"%}
{% include "elections/includes/eu_results.html" with card=0 %}
{% endif %}
{% if postelection.election.description %}
<div class="ds-details">
<details>
<summary>
<h2>
<span aria-hidden="true">{% trans "About this position" %}
</span>
</h2>
</summary>
{% blocktrans with description=postelection.election.description|markdown %} {{ description }}{% endblocktrans%}
</details>
</div>
{% endif %}

<ul class="ds-details">
{% if postelection.election.description %}
<li>
<details>
<summary>
<h2>
<span aria-hidden="true">{% trans "About this position" %}
</span>
</h2>
</summary>
{% blocktrans with description=postelection.election.description|markdown %} {{ description }}{% endblocktrans%}
</details>
</li>
{% endif %}

{% if postelection.election.is_city_of_london_local_election and not postelection.past_registration_deadline and not postelection.cancelled %}
<li>
{% include "elections/includes/_city_of_london_registration_details.html" %}
</li>
{% endif %}
</ul>

<p>
{% if postelection.election.in_past %}
Expand Down Expand Up @@ -128,7 +137,7 @@ <h2>
<li><a href="#requirements">{% trans "Voter ID requirements" %}</a></li>
{% endif %}

{% if is_before_registration_deadline %}
{% if global_registration_card.show %}
<li><a href="#register">{% trans "Register to vote" %}</a></li>
{% endif %}
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ <h3>
<li><a href="#requirements">{% trans "Voter ID requirements" %}</a></li>
{% endif %}

{% if is_before_registration_deadline %}
{% if global_registration_card.show %}
<li><a href="#register">{% trans "Register to vote" %}</a></li>
{% endif %}
</ul>
Expand Down
4 changes: 2 additions & 2 deletions wcivf/apps/elections/templates/elections/postcode_view.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ <h3>Your area</h3>
{% include "elections/includes/_voter_id.html" %}
{% endif %}

{% if is_before_registration_deadline %}
{% include "elections/includes/_registration_details.html" with postelection=postelections.0 council=council %}
{% if global_registration_card.show %}
{% include "elections/includes/_registration_details.html" with card=global_registration_card council=council %}
{% endif %}

{% if not messages %}
Expand Down
26 changes: 12 additions & 14 deletions wcivf/apps/elections/tests/test_postcode_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,6 @@ def test_multiple_elections_london(self, mock_response, client):
election__election_date="2024-05-06",
election__name="Cities of London and Westminster by-election",
)
parl_london.is_before_registration_deadline = True
local_london.is_before_registration_deadline = True

mock_response.json.return_value["dates"].extend(
[
Expand Down Expand Up @@ -374,8 +372,6 @@ def test_no_polling_station_shows_council_details(
post__territory="ENG",
)

local.is_before_registration_deadline = True

mock_response.json.return_value["dates"].extend(
[
{
Expand Down Expand Up @@ -427,8 +423,6 @@ def council_and_registration_details_differ(self, mock_response, client):
post__territory="ENG",
)

local.is_before_registration_deadline = True

mock_response.json.return_value["dates"].extend(
[
{
Expand Down Expand Up @@ -618,27 +612,31 @@ def test_show_polling_card(self, view_obj, post_elections):

@freeze_time("2020-01-01")
@pytest.mark.django_db
def test_is_before_registration_deadline(self, view_obj):
def test_global_registration_card(self, view_obj):
post_elections = [
PostElectionFactory(
election__slug="local.city-of-london.2020-05-06",
ballot_paper_id="local.croydon.wardname1.2020-05-06",
election__slug="local.croydon.2020-05-06",
election__election_date="2020-05-06",
contested=True,
cancelled=False,
post__territory="ENG",
),
PostElectionFactory(
election__slug="local.city-of-london.2020-05-06",
ballot_paper_id="local.croydon.wardname2.2020-05-06",
election__slug="local.croydon.2020-05-06",
election__election_date="2020-05-06",
contested=False,
cancelled=True,
post__territory="ENG",
),
]
assert (
view_obj.is_before_registration_deadline(
post_elections=post_elections
)
is True
card = view_obj.get_global_registration_card(
post_elections=post_elections
)
assert card["show"] is True
assert card["registration_deadline"] == "20 April 2020"
assert card["election_date"] == "2020-05-06"

def test_num_ballots_no_parish_election(self, view_obj, mocker):
future_post_election = mocker.MagicMock(spec=PostElection, past_date=0)
Expand Down
24 changes: 19 additions & 5 deletions wcivf/apps/elections/views/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,21 @@ def get_advance_voting_station_info(self, polling_station: Optional[dict]):
advance_voting_station["open_in_future"] = open_in_future
return advance_voting_station

def is_before_registration_deadline(self, post_elections):
if not post_elections:
def get_global_registration_card(self, post_elections):
# City of London local elections have different
# registration rules to every other election
non_city_of_london_ballots = [
ballot
for ballot in post_elections
if not ballot.election.is_city_of_london_local_election
and not ballot.cancelled
]

if not non_city_of_london_ballots:
return False
election = post_elections[0].election
country = post_elections[0].post.territory
next_ballot = non_city_of_london_ballots[0]
election = next_ballot.election
country = next_ballot.post.territory

if not country:
country = Country.ENGLAND
Expand All @@ -194,7 +204,11 @@ def is_before_registration_deadline(self, post_elections):
}.get(country)
election = from_election_id(election_id=election.slug, country=country)
event = TimetableEvent.REGISTRATION_DEADLINE
return election.is_before(event)
return {
"show": election.is_before(event),
"registration_deadline": next_ballot.registration_deadline,
"election_date": next_ballot.election.election_date,
}


class LogLookUpMixin(object):
Expand Down
10 changes: 5 additions & 5 deletions wcivf/apps/elections/views/postcode_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ def get_context_data(self, **kwargs):
context["show_polling_card"] = self.show_polling_card(
context["postelections"]
)
context[
"is_before_registration_deadline"
] = self.is_before_registration_deadline(context["postelections"])
context["global_registration_card"] = self.get_global_registration_card(
context["postelections"]
)
context["people_for_post"] = {}
for postelection in context["postelections"]:
postelection.people = self.people_for_ballot(postelection)
Expand Down Expand Up @@ -406,8 +406,8 @@ def get_context_data(self, **kwargs):
context["show_polling_card"] = True
context["polling_station"] = self.get_polling_station()
context[
"is_before_registration_deadline"
] = PostcodeView().is_before_registration_deadline(
"global_registration_card"
] = PostcodeView().get_global_registration_card(
context["postelections"]
)
context["registration"] = self.get_registration()
Expand Down

0 comments on commit 36d9c34

Please sign in to comment.