diff --git a/djangoproject/templates/foundation/meeting_snippet.html b/djangoproject/templates/foundation/meeting_snippet.html index 0e72198eb0..92dbf013d5 100644 --- a/djangoproject/templates/foundation/meeting_snippet.html +++ b/djangoproject/templates/foundation/meeting_snippet.html @@ -23,3 +23,13 @@
+ {% blocktranslate trimmed %} + Board meetings are generally the second Thursday of the month but are + occasionally rescheduled for attendance. + {% endblocktranslate %} + {% if next_meeting_date %} + {% translate "The next meeting is scheduled for: " context "Following meetings schedule" %}{{next_meeting_date|date:"DATE_FORMAT"}} + {% endif %} + +
diff --git a/foundation/migrations/0008_meeting_next_meeting_date.py b/foundation/migrations/0008_meeting_next_meeting_date.py new file mode 100644 index 0000000000..7e9220a5be --- /dev/null +++ b/foundation/migrations/0008_meeting_next_meeting_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2 on 2025-09-24 13:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('foundation', '0007_boardmember_account_protect'), + ] + + operations = [ + migrations.AddField( + model_name='meeting', + name='next_meeting_date', + field=models.DateField(blank=True, help_text="This will be shown on the website as the board's next meeting date. The latest meeting's Next Meeting Date will be used.", null=True), + ), + ] diff --git a/foundation/models.py b/foundation/models.py index 7ae1fa4acf..4547d310df 100644 --- a/foundation/models.py +++ b/foundation/models.py @@ -95,6 +95,13 @@ class Meeting(models.Model): ) treasurer_report = models.TextField(blank=True) treasurer_report_html = models.TextField(editable=False) + next_meeting_date = models.DateField( + null=True, + blank=True, + help_text=_( + "This will be shown on the website as the board's next meeting date. The latest meeting's Next Meeting Date will be used." + ), + ) def __str__(self): return "{}, {}".format(self.title, date_format(self.date, "F j, Y")) diff --git a/foundation/templatetags/meetings.py b/foundation/templatetags/meetings.py index 80aeec8e83..a8098e355c 100644 --- a/foundation/templatetags/meetings.py +++ b/foundation/templatetags/meetings.py @@ -8,4 +8,5 @@ @register.inclusion_tag("foundation/meeting_snippet.html") def render_latest_meeting_minute_entries(num): meetings = Meeting.objects.order_by("-date").prefetch_related("business")[:num] - return {"meetings": meetings} + next_meeting_date = meetings[0].next_meeting_date if meetings else None + return {"meetings": meetings, "next_meeting_date": next_meeting_date} diff --git a/foundation/tests.py b/foundation/tests.py index 38569f3756..69db2891af 100644 --- a/foundation/tests.py +++ b/foundation/tests.py @@ -83,7 +83,9 @@ def test_latest_meeting_minutes(self): "title": "DSF Board monthly meeting", } latest_meeting = Meeting.objects.create( - date=date(2023, 5, 12), **common_meeting_data + date=date(2023, 5, 12), + next_meeting_date=date(2023, 6, 13), + **common_meeting_data ) previous_meeting = Meeting.objects.create( date=date(2023, 4, 12), **common_meeting_data @@ -104,6 +106,9 @@ def test_latest_meeting_minutes(self): self.assertContains(response, "Latest DSF meeting minutes") self.assertContains(response, "DSF Board monthly meeting, May 12, 2023") + self.assertContains( + response, "The next meeting is scheduled for: June 13, 2023" + ) self.assertContains(response, latest_meeting.get_absolute_url()) self.assertContains(response, "DSF Board monthly meeting, April 12, 2023") self.assertContains(response, previous_meeting.get_absolute_url()) @@ -113,3 +118,33 @@ def test_latest_meeting_minutes(self): self.assertContains(response, "Business item 1") self.assertContains(response, "Business item 2") self.assertContains(response, "Business item 3") + + def test_latest_meeting_minutes_without_next_meeting_date(self): + common_meeting_data = { + "slug": "dsf-board-monthly-meeting", + "leader": self.member, + "treasurer_report": "Hello World", + "title": "DSF Board monthly meeting", + } + latest_meeting = Meeting.objects.create( + date=date(2023, 5, 12), + next_meeting_date=None, # Explicitly left out + **common_meeting_data + ) + Meeting.objects.create(date=date(2023, 4, 12), **common_meeting_data) + + Business.objects.create( + title="Business item 1", + body="Example", + body_html="Example", + business_type="New", + meeting=latest_meeting, + ) + + response = self.client.get(reverse("foundation_meeting_archive_index")) + + self.assertContains(response, "Latest DSF meeting minutes") + self.assertContains(response, "DSF Board monthly meeting, May 12, 2023") + + # Key check for no meeting schedule + self.assertNotContains(response, "The next meeting is scheduled for: ")