diff --git a/schemes/views/schemes/milestones.py b/schemes/views/schemes/milestones.py
index 76699037..537771f6 100644
--- a/schemes/views/schemes/milestones.py
+++ b/schemes/views/schemes/milestones.py
@@ -146,10 +146,6 @@ class ChangeMilestoneDatesForm(FlaskForm): # type: ignore
required_message="Enter a construction completed planned date",
invalid_message="Construction completed planned date must be a real date",
)
- construction_completed_actual = MilestoneDateField(
- required_message="Enter a construction completed actual date",
- invalid_message="Construction completed actual date must be a real date",
- )
@classmethod
def from_domain(cls, milestones: SchemeMilestones) -> ChangeMilestoneDatesForm:
@@ -181,9 +177,6 @@ def from_domain(cls, milestones: SchemeMilestones) -> ChangeMilestoneDatesForm:
construction_completed_planned=milestones.get_current_status_date(
Milestone.CONSTRUCTION_COMPLETED, ObservationType.PLANNED
),
- construction_completed_actual=milestones.get_current_status_date(
- Milestone.CONSTRUCTION_COMPLETED, ObservationType.ACTUAL
- ),
)
def update_domain(self, milestones: SchemeMilestones, now: datetime) -> None:
@@ -213,11 +206,7 @@ def update_milestone(planned: date | None, actual: date | None, milestone: Miles
self.construction_started_actual.data,
Milestone.CONSTRUCTION_STARTED,
)
- update_milestone(
- self.construction_completed_planned.data,
- self.construction_completed_actual.data,
- Milestone.CONSTRUCTION_COMPLETED,
- )
+ update_milestone(self.construction_completed_planned.data, None, Milestone.CONSTRUCTION_COMPLETED)
@dataclass(frozen=True)
diff --git a/schemes/views/templates/scheme/milestones.html b/schemes/views/templates/scheme/milestones.html
index df0591f6..57a6b29a 100644
--- a/schemes/views/templates/scheme/milestones.html
+++ b/schemes/views/templates/scheme/milestones.html
@@ -44,7 +44,7 @@
Change milestone dates
{{ milestone("Preliminary design completed", form.preliminary_design_completed_planned, form.preliminary_design_completed_actual) }}
{{ milestone("Detailed design completed", form.detailed_design_completed_planned, form.detailed_design_completed_actual) }}
{{ milestone("Construction started", form.construction_started_planned, form.construction_started_actual) }}
- {{ milestone("Construction completed", form.construction_completed_planned, form.construction_completed_actual) }}
+ {{ milestone("Construction completed", form.construction_completed_planned, None) }}
{{ govukButton({
@@ -71,15 +71,17 @@
{{ name }}
}
}) }}
-
- {{ actual_field(params={
- "fieldset": {
- "describedBy": "date-hint",
- "legend": {
- "text": "Actual date"
+ {% if actual_field %}
+
+ {{ actual_field(params={
+ "fieldset": {
+ "describedBy": "date-hint",
+ "legend": {
+ "text": "Actual date"
+ }
}
- }
- }) }}
-
+ }) }}
+
+ {% endif %}
{%- endmacro %}
diff --git a/tests/integration/pages.py b/tests/integration/pages.py
index 178461bc..61c4ec66 100644
--- a/tests/integration/pages.py
+++ b/tests/integration/pages.py
@@ -399,7 +399,8 @@ def __init__(self, heading: Tag):
grid_row = heading.find_next_sibling("div", class_="govuk-grid-row")
assert isinstance(grid_row, Tag)
self.planned = DateComponent(one(grid_row.select("fieldset:has(legend:-soup-contains('Planned date'))")))
- self.actual = DateComponent(one(grid_row.select("fieldset:has(legend:-soup-contains('Actual date'))")))
+ actual_tag = grid_row.select_one("fieldset:has(legend:-soup-contains('Actual date'))")
+ self.actual = DateComponent(actual_tag) if actual_tag else None
class DateComponent:
diff --git a/tests/integration/test_scheme_milestones.py b/tests/integration/test_scheme_milestones.py
index 40518270..4735bdea 100644
--- a/tests/integration/test_scheme_milestones.py
+++ b/tests/integration/test_scheme_milestones.py
@@ -151,20 +151,24 @@ def test_milestones_form_shows_fields(self, schemes: SchemeRepository, client: F
assert (
change_milestone_dates_page.form.feasibility_design_completed.planned.name
== "feasibility_design_completed_planned"
+ and change_milestone_dates_page.form.feasibility_design_completed.actual
and change_milestone_dates_page.form.feasibility_design_completed.actual.name
== "feasibility_design_completed_actual"
and change_milestone_dates_page.form.preliminary_design_completed.planned.name
== "preliminary_design_completed_planned"
+ and change_milestone_dates_page.form.preliminary_design_completed.actual
and change_milestone_dates_page.form.preliminary_design_completed.actual.name
== "preliminary_design_completed_actual"
and change_milestone_dates_page.form.detailed_design_completed.planned.name
== "detailed_design_completed_planned"
+ and change_milestone_dates_page.form.detailed_design_completed.actual
and change_milestone_dates_page.form.detailed_design_completed.actual.name
== "detailed_design_completed_actual"
and change_milestone_dates_page.form.construction_started.planned.name == "construction_started_planned"
+ and change_milestone_dates_page.form.construction_started.actual
and change_milestone_dates_page.form.construction_started.actual.name == "construction_started_actual"
and change_milestone_dates_page.form.construction_completed.planned.name == "construction_completed_planned"
- and change_milestone_dates_page.form.construction_completed.actual.name == "construction_completed_actual"
+ and change_milestone_dates_page.form.construction_completed.actual is None
)
def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: FlaskClient) -> None:
@@ -174,7 +178,7 @@ def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: Fla
id_=1,
effective=DateRange(datetime(2020, 1, 1, 12), None),
milestone=Milestone.CONSTRUCTION_STARTED,
- observation_type=ObservationType.ACTUAL,
+ observation_type=ObservationType.PLANNED,
status_date=date(2020, 1, 2),
source=DataSource.ATF4_BID,
)
@@ -184,7 +188,7 @@ def test_milestones_form_shows_date(self, schemes: SchemeRepository, client: Fla
change_milestone_dates_page = ChangeMilestoneDatesPage.open(client, id_=1)
assert change_milestone_dates_page.title == "Update your capital schemes - Active Travel England - GOV.UK"
- assert change_milestone_dates_page.form.construction_started.actual.value == "2 1 2020"
+ assert change_milestone_dates_page.form.construction_started.planned.value == "2 1 2020"
def test_milestones_form_shows_confirm(self, schemes: SchemeRepository, client: FlaskClient) -> None:
schemes.add(build_scheme(id_=1, name="Wirral Package", authority_id=1))
@@ -234,7 +238,7 @@ def test_milestones_updates_milestones(
id_=1,
effective=DateRange(datetime(2020, 1, 1, 12), None),
milestone=Milestone.CONSTRUCTION_STARTED,
- observation_type=ObservationType.ACTUAL,
+ observation_type=ObservationType.PLANNED,
status_date=date(2020, 1, 2),
source=DataSource.ATF4_BID,
)
@@ -242,7 +246,7 @@ def test_milestones_updates_milestones(
schemes.add(scheme)
client.post(
- "/schemes/1/milestones", data={"csrf_token": csrf_token, "construction_started_actual": ["3", "1", "2020"]}
+ "/schemes/1/milestones", data={"csrf_token": csrf_token, "construction_started_planned": ["3", "1", "2020"]}
)
actual_scheme = schemes.get(1)
@@ -254,7 +258,7 @@ def test_milestones_updates_milestones(
assert (
milestone_revision2.effective == DateRange(datetime(2020, 2, 1, 13), None)
and milestone_revision2.milestone == Milestone.CONSTRUCTION_STARTED
- and milestone_revision2.observation_type == ObservationType.ACTUAL
+ and milestone_revision2.observation_type == ObservationType.PLANNED
and milestone_revision2.status_date == date(2020, 1, 3)
and milestone_revision2.source == DataSource.AUTHORITY_UPDATE
)
@@ -275,7 +279,7 @@ def test_cannot_milestones_when_error(
id_=1,
effective=DateRange(datetime(2020, 1, 1, 12), None),
milestone=Milestone.CONSTRUCTION_STARTED,
- observation_type=ObservationType.ACTUAL,
+ observation_type=ObservationType.PLANNED,
status_date=date(2020, 1, 2),
source=DataSource.ATF4_BID,
)
@@ -286,7 +290,7 @@ def test_cannot_milestones_when_error(
client.post(
"/schemes/1/milestones",
data=self.empty_change_milestone_dates_form()
- | {"csrf_token": csrf_token, "construction_started_actual": ["x", "x", "x"]},
+ | {"csrf_token": csrf_token, "construction_started_planned": ["x", "x", "x"]},
)
)
@@ -294,13 +298,13 @@ def test_cannot_milestones_when_error(
change_milestone_dates_page.title == "Error: Update your capital schemes - Active Travel England - GOV.UK"
)
assert change_milestone_dates_page.errors and list(change_milestone_dates_page.errors) == [
- "Construction started actual date must be a real date"
+ "Construction started planned date must be a real date"
]
assert (
- change_milestone_dates_page.form.construction_started.actual.is_errored
- and change_milestone_dates_page.form.construction_started.actual.error
- == "Error: Construction started actual date must be a real date"
- and change_milestone_dates_page.form.construction_started.actual.value == "x x x"
+ change_milestone_dates_page.form.construction_started.planned.is_errored
+ and change_milestone_dates_page.form.construction_started.planned.error
+ == "Error: Construction started planned date must be a real date"
+ and change_milestone_dates_page.form.construction_started.planned.value == "x x x"
)
actual_scheme = schemes.get(1)
assert actual_scheme
@@ -310,7 +314,7 @@ def test_cannot_milestones_when_error(
milestone_revision1.id == 1
and milestone_revision1.effective == DateRange(datetime(2020, 1, 1, 12), None)
and milestone_revision1.milestone == Milestone.CONSTRUCTION_STARTED
- and milestone_revision1.observation_type == ObservationType.ACTUAL
+ and milestone_revision1.observation_type == ObservationType.PLANNED
and milestone_revision1.status_date == date(2020, 1, 2)
and milestone_revision1.source == DataSource.ATF4_BID
)
@@ -381,5 +385,4 @@ def empty_change_milestone_dates_form(self) -> dict[str, list[str]]:
"construction_started_planned": empty_date,
"construction_started_actual": empty_date,
"construction_completed_planned": empty_date,
- "construction_completed_actual": empty_date,
}
diff --git a/tests/views/schemes/test_milestones.py b/tests/views/schemes/test_milestones.py
index d963d198..f04ee78e 100644
--- a/tests/views/schemes/test_milestones.py
+++ b/tests/views/schemes/test_milestones.py
@@ -177,7 +177,6 @@ class TestChangeMilestoneDatesForm:
"construction_started_planned",
"construction_started_actual",
"construction_completed_planned",
- "construction_completed_actual",
]
field_names_milestones_observation_types = [
("feasibility_design_completed_planned", Milestone.FEASIBILITY_DESIGN_COMPLETED, ObservationType.PLANNED),
@@ -189,7 +188,6 @@ class TestChangeMilestoneDatesForm:
("construction_started_planned", Milestone.CONSTRUCTION_STARTED, ObservationType.PLANNED),
("construction_started_actual", Milestone.CONSTRUCTION_STARTED, ObservationType.ACTUAL),
("construction_completed_planned", Milestone.CONSTRUCTION_COMPLETED, ObservationType.PLANNED),
- ("construction_completed_actual", Milestone.CONSTRUCTION_COMPLETED, ObservationType.ACTUAL),
]
@pytest.mark.parametrize("field_name, milestone, observation_type", field_names_milestones_observation_types)
@@ -233,7 +231,6 @@ def test_from_domain_when_minimal(self) -> None:
and form.construction_started_planned.data is None
and form.construction_started_actual.data is None
and form.construction_completed_planned.data is None
- and form.construction_completed_actual.data is None
)
@pytest.mark.parametrize("field_name, milestone, observation_type", field_names_milestones_observation_types)
@@ -329,6 +326,22 @@ def test_update_domain_ignores_unchanged_dates(
and milestone_revision1.source == DataSource.ATF4_BID
)
+ def test_update_domain_ignores_construction_completed_actual_date(self) -> None:
+ form = ChangeMilestoneDatesForm(
+ formdata=MultiDict(
+ [
+ ("construction_completed_actual", "2"),
+ ("construction_completed_actual", "1"),
+ ("construction_completed_actual", "2020"),
+ ]
+ )
+ )
+ milestones = SchemeMilestones()
+
+ form.update_domain(milestones, now=datetime(2020, 2, 1, 13))
+
+ assert not milestones.milestone_revisions
+
@pytest.mark.parametrize("field_name", field_names)
def test_no_errors_when_valid(self, field_name: str) -> None:
form = ChangeMilestoneDatesForm(
@@ -361,7 +374,6 @@ def test_date_without_initial_value_is_optional(self, field_name: str) -> None:
("construction_started_planned", "Enter a construction started planned date"),
("construction_started_actual", "Enter a construction started actual date"),
("construction_completed_planned", "Enter a construction completed planned date"),
- ("construction_completed_actual", "Enter a construction completed actual date"),
],
)
@pytest.mark.parametrize(
@@ -398,7 +410,6 @@ def test_date_with_initial_value_is_required(
("construction_started_planned", "Construction started planned date must be a real date"),
("construction_started_actual", "Construction started actual date must be a real date"),
("construction_completed_planned", "Construction completed planned date must be a real date"),
- ("construction_completed_actual", "Construction completed actual date must be a real date"),
],
)
@pytest.mark.parametrize(