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

[#3049] Fix end-date of plan can precede that of action templates #1630

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/open_inwoner/plans/forms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import timedelta
from datetime import date, timedelta
from io import BytesIO

from django import forms
Expand Down Expand Up @@ -59,6 +59,7 @@ def clean(self):
goal = cleaned_data.get("goal")
template = cleaned_data.get("template")
plan_contacts = cleaned_data.get("plan_contacts")
end_date = cleaned_data.get("end_date")

if not plan_contacts or (
plan_contacts and not plan_contacts.exclude(pk=self.user.pk)
Expand All @@ -71,6 +72,27 @@ def clean(self):
"goal", _("This field is required when not using a template")
)

# Verify that the selected end date of the plan does not precede the
# would-be dates of the actions in the selected template (if any)
if template and end_date:
template_row = PlanTemplate.objects.get(id=template.id)

actionTemplates = template_row.actiontemplates.all()

if actionTemplates:
latest_end_in_days = max([a.end_in_days for a in actionTemplates])

today = date.today()
actions_end_date = today + timedelta(days=latest_end_in_days)

if end_date < actions_end_date:
self.add_error(
"end_date",
_(
"The end date of the plan cannot precede the end dates of the actions in the selected template."
),
)

def clean_plan_contacts(self):
# Make sure current user exists in plan_contacts when editing form
data = self.cleaned_data["plan_contacts"]
Expand Down
44 changes: 42 additions & 2 deletions src/open_inwoner/plans/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import date
from datetime import date, timedelta
from unittest.mock import Mock, patch

from django.contrib.messages import get_messages
Expand Down Expand Up @@ -440,11 +440,19 @@ def test_plan_create_plan_with_template_and_file(self):
def test_plan_create_plan_with_template_and_actions(self):
plan_template = PlanTemplateFactory(file=None)
ActionTemplateFactory(plan_template=plan_template)

# Necessary to make sure the end date of the actions
# is before the end date of the plan itself
for actionTemplate in plan_template.actiontemplates.all():
actionTemplate.end_in_days = 7
actionTemplate.save()

self.assertEqual(Plan.objects.count(), 1)
response = self.app.get(self.create_url, user=self.user)
form = response.forms["plan-form"]
form["title"] = "Plan"
form["end_date"] = "2022-01-01"
today = date.today()
form["end_date"] = today + timedelta(days=10)
form["plan_contacts"] = [self.contact.pk]
form["template"] = plan_template.pk
response = form.submit().follow()
Expand Down Expand Up @@ -483,6 +491,38 @@ def test_plan_create_plan_validation_error_reselects_template_and_contact(self):
elem = response.pyquery("#id_plan_contacts_1")[0]
self.assertEqual(elem.attrib.get("checked"), "checked")

def test_plan_create_plan_end_date_cannot_precede_action_end_dates(self):
plan_template = PlanTemplateFactory(file=None)
ActionTemplateFactory(plan_template=plan_template)
# make sure we have only one plan
self.assertEqual(Plan.objects.count(), 1)

# Purposely make the dates of the actions much higher
# than the date of the plan
for actionTemplate in plan_template.actiontemplates.all():
actionTemplate.end_in_days = 10000
actionTemplate.save()

response = self.app.get(self.create_url, user=self.user)
form = response.forms["plan-form"]
form["title"] = "Plan"
form["end_date"] = "2025-02-23"
form["plan_contacts"] = [self.contact.pk]
form["template"] = plan_template.pk
response = form.submit()
self.assertEqual(response.status_code, 200)

# Confirm the mistake was caught
self.assertContains(
response,
_(
"The end date of the plan cannot precede the end dates of the actions in the selected template."
),
)

# nothing was created
self.assertEqual(Plan.objects.count(), 1)

def test_plan_create_contains_contact_create_link_when_no_contacts_exist(self):
self.user.user_contacts.remove(self.contact)
response = self.app.get(self.create_url, user=self.user)
Expand Down
Loading