diff --git a/manage_breast_screening/mammograms/jinja2/mammograms/show/participant_details.jinja b/manage_breast_screening/mammograms/jinja2/mammograms/show/participant_details.jinja index 754ac365f..e3b6eb59c 100644 --- a/manage_breast_screening/mammograms/jinja2/mammograms/show/participant_details.jinja +++ b/manage_breast_screening/mammograms/jinja2/mammograms/show/participant_details.jinja @@ -4,7 +4,7 @@ {% from 'nhsuk/components/back-link/macro.jinja' import backLink %} {% from 'components/appointment-status/macro.jinja' import appointment_status %} {% from 'components/appointment-header/macro.jinja' import appointment_header %} -{% from 'components/participant-details/template.jinja' import participant_details %} +{% from 'components/participant-details/participant_details.jinja' import participant_details %} {% from 'components/participant-details/contact_details.jinja' import contact_details %} {% from 'components/secondary-navigation/macro.jinja' import app_secondary_navigation %} {% from 'mammograms/special_appointments/special_appointment_banner.jinja' import special_appointment_banner %} diff --git a/manage_breast_screening/participants/jinja2/components/participant-details/template.jinja b/manage_breast_screening/participants/jinja2/components/participant-details/participant_details.jinja similarity index 100% rename from manage_breast_screening/participants/jinja2/components/participant-details/template.jinja rename to manage_breast_screening/participants/jinja2/components/participant-details/participant_details.jinja diff --git a/manage_breast_screening/participants/jinja2/components/participant-details/personal_details.jinja b/manage_breast_screening/participants/jinja2/components/participant-details/personal_details.jinja deleted file mode 100644 index 9d178652a..000000000 --- a/manage_breast_screening/participants/jinja2/components/participant-details/personal_details.jinja +++ /dev/null @@ -1,55 +0,0 @@ -{% from "nhsuk/components/card/macro.jinja" import card %} -{% from "nhsuk/components/summary-list/macro.jinja" import summaryList %} -{% from "components/participant-details/summary_list_rows.jinja" import date_of_birth_and_age_html, ethnicity_html %} - -{% macro personal_details(presented_participant, return_url) %} - {% call card({ - "heading": "Personal details" - }) %} - {{ summaryList({ - "rows": [ - { - "key": { - "text": "NHS Number" - }, - "value": { - "text": presented_participant.nhs_number - } - }, - { - "key": { - "text": "Full name" - }, - "value": { - "text": presented_participant.full_name - } - }, - { - "key": { - "text": "Gender" - }, - "value": { - "text": presented_participant.gender - } - }, - { - "key": { - "text": "Date of birth" - }, - "value": { - "html": date_of_birth_and_age_html(presented_participant) | safe - } - }, - { - "key": { - "text": "Ethnicity" - }, - "value": { - "html": ethnicity_html(presented_participant) | safe - }, - "actions": presented_participant.ethnicity_actions(return_url) - }, - ] - }) }} - {% endcall %} -{% endmacro %} diff --git a/manage_breast_screening/participants/jinja2/participants/show.jinja b/manage_breast_screening/participants/jinja2/participants/show.jinja deleted file mode 100644 index 49a2d9492..000000000 --- a/manage_breast_screening/participants/jinja2/participants/show.jinja +++ /dev/null @@ -1,25 +0,0 @@ -{% extends 'layout-app.jinja' %} -{% from 'nhsuk/components/back-link/macro.jinja' import backLink %} -{% from 'nhsuk/components/card/macro.jinja' import card %} -{% from 'nhsuk/components/tag/macro.jinja' import tag %} -{% from 'nhsuk/components/summary-list/macro.jinja' import summaryList %} -{% from 'components/participant-details/appointments.jinja' import appointments %} -{% from 'components/participant-details/contact_details.jinja' import contact_details %} -{% from 'components/participant-details/personal_details.jinja' import personal_details %} -{% from 'components/participant-details/screening_details.jinja' import screening_details %} - - -{% block page_content %} -
-
-

- {{ heading }} -

- - {{ personal_details(presented_participant=presented_participant) }} - {{ contact_details(presented_participant=presented_participant) }} - {{ screening_details(presented_mammograms=presented_mammograms) }} - {{ appointments(presented_appointments=presented_appointments) }} -
-
-{% endblock page_content %} diff --git a/manage_breast_screening/participants/models/appointment.py b/manage_breast_screening/participants/models/appointment.py index e5b32bafa..10da86145 100644 --- a/manage_breast_screening/participants/models/appointment.py +++ b/manage_breast_screening/participants/models/appointment.py @@ -39,6 +39,9 @@ def checked_in(self): def in_progress(self): return self.in_status(AppointmentStatus.IN_PROGRESS) + def for_participant(self, participant_id): + return self.filter(screening_episode__participant_id=participant_id) + def complete(self): return self.in_status( AppointmentStatus.CANCELLED, diff --git a/manage_breast_screening/participants/tests/jinja2/test_personal_details.py b/manage_breast_screening/participants/tests/jinja2/test_personal_details.py deleted file mode 100644 index a27fa0986..000000000 --- a/manage_breast_screening/participants/tests/jinja2/test_personal_details.py +++ /dev/null @@ -1,64 +0,0 @@ -from textwrap import dedent - -import pytest -from pytest_django.asserts import assertInHTML - -from manage_breast_screening.participants.presenters import ParticipantPresenter - -from ..factories import ParticipantFactory - - -class TestPersonalDetails: - @pytest.fixture - def presenter(self): - return ParticipantPresenter( - ParticipantFactory.build( - ethnic_background_id="english_welsh_scottish_ni_british" - ) - ) - - def test_personal_details(self, presenter, jinja_env): - template = jinja_env.from_string( - dedent( - r""" - {% from 'components/participant-details/personal_details.jinja' import personal_details %} - {{ personal_details(presenter) }} - """ - ) - ) - - response = template.render({"presenter": presenter}) - - assertInHTML( - '

Personal details

', - response, - ) - - assertInHTML('
NHS Number
', response) - assertInHTML( - f'
{presenter.nhs_number}
', - response, - ) - - assertInHTML('
Full name
', response) - assertInHTML( - f'
{presenter.full_name}
', - response, - ) - - assertInHTML('
Gender
', response) - assertInHTML( - f'
{presenter.gender}
', response - ) - - assertInHTML('
Date of birth
', response) - assertInHTML( - f'
{presenter.date_of_birth}
({presenter.age})
', - response, - ) - - assertInHTML('
Ethnicity
', response) - assertInHTML( - '
White (English, Welsh, Scottish, Northern Irish or British)
', - response, - ) diff --git a/manage_breast_screening/participants/tests/test_models.py b/manage_breast_screening/participants/tests/test_models.py index f26f11181..8f1c6e04f 100644 --- a/manage_breast_screening/participants/tests/test_models.py +++ b/manage_breast_screening/participants/tests/test_models.py @@ -240,6 +240,21 @@ def test_order_by_starts_at(self): [late, middle, early], ) + def test_for_participant(self): + a = AppointmentFactory.create() + b = AppointmentFactory.create( + screening_episode__participant=a.screening_episode.participant + ) + AppointmentFactory.create() + + assertQuerySetEqual( + models.Appointment.objects.for_participant( + a.screening_episode.participant_id + ), + [a, b], + ordered=False, + ) + @pytest.mark.django_db class TestEagerLoadCurrentStatus: def test_eager_loads_most_recent_status_with_created_by( diff --git a/manage_breast_screening/participants/tests/test_views.py b/manage_breast_screening/participants/tests/test_views.py index e6d4e7fd1..685251ed3 100644 --- a/manage_breast_screening/participants/tests/test_views.py +++ b/manage_breast_screening/participants/tests/test_views.py @@ -1,5 +1,6 @@ import pytest from django.urls import reverse +from pytest_django.asserts import assertRedirects from manage_breast_screening.participants.tests.factories import ( AppointmentFactory, @@ -9,14 +10,33 @@ @pytest.mark.django_db class TestShowParticipant: - def test_renders_response(self, clinical_user_client): + def test_redirects_to_appointment_participant_details(self, clinical_user_client): # Create an appointment with the current provider so the participant is accessible participant = ParticipantFactory.create() - AppointmentFactory.create( + appointment = AppointmentFactory.create( screening_episode__participant=participant, clinic_slot__clinic__setting__provider=clinical_user_client.current_provider, ) response = clinical_user_client.http.get( reverse("participants:show", kwargs={"pk": participant.pk}), ) - assert response.status_code == 200 + + assertRedirects( + response, + reverse( + "mammograms:participant_details", + kwargs={"pk": appointment.pk}, + ), + ) + + def test_redirects_to_home_if_no_appointment(self, clinical_user_client): + participant = ParticipantFactory.create() + + response = clinical_user_client.http.get( + reverse("participants:show", kwargs={"pk": participant.pk}), + ) + + assertRedirects( + response, + reverse("clinics:index"), + ) diff --git a/manage_breast_screening/participants/views.py b/manage_breast_screening/participants/views.py index 57cd8ce42..370718d04 100644 --- a/manage_breast_screening/participants/views.py +++ b/manage_breast_screening/participants/views.py @@ -5,12 +5,11 @@ from django.shortcuts import redirect, render from django.urls import reverse -from manage_breast_screening.mammograms.presenters import LastKnownMammogramPresenter +from manage_breast_screening.participants.models.appointment import Appointment from manage_breast_screening.participants.services import fetch_most_recent_provider from .forms import EthnicityForm, ParticipantReportedMammogramForm -from .models import Participant, ParticipantReportedMammogram -from .presenters import ParticipantAppointmentsPresenter, ParticipantPresenter +from .models import Participant logger = getLogger(__name__) @@ -35,41 +34,18 @@ def parse_return_url(request, default: str) -> str: def show(request, pk): provider = request.user.current_provider try: - participant = provider.participants.get(pk=pk) - except Participant.DoesNotExist: - raise Http404("Participant not found") - presented_participant = ParticipantPresenter(participant) - - appointments = participant.appointments.order_by_starts_at( - desc=True - ).select_related("clinic_slot__clinic__setting") - - presented_appointments = ParticipantAppointmentsPresenter( - past_appointments=list(appointments.past()), - upcoming_appointments=list(appointments.upcoming()), - ) - - last_known_mammograms = ParticipantReportedMammogram.objects.filter( - participant_id=pk - ).order_by("-created_at") - - presented_mammograms = LastKnownMammogramPresenter( - last_known_mammograms, - participant_pk=pk, - current_url=request.path, - ) + appointment_id = ( + provider.appointments.select_related("clinic_slot") + .for_participant(pk) + .order_by_starts_at(desc=True)[0:1] + .values_list("id", flat=True) + .get() + ) + except Appointment.DoesNotExist: + logger.exception(f"Appointment not found for participant {pk}") + return redirect(reverse("clinics:index")) - return render( - request, - "participants/show.jinja", - context={ - "presented_participant": presented_participant, - "presented_appointments": presented_appointments, - "presented_mammograms": presented_mammograms, - "heading": participant.full_name, - "page_title": "Participant", - }, - ) + return redirect("mammograms:participant_details", pk=appointment_id) def edit_ethnicity(request, pk): diff --git a/manage_breast_screening/tests/system/administrative/test_participant_record.py b/manage_breast_screening/tests/system/administrative/test_participant_record.py index 92535586e..72936dc6a 100644 --- a/manage_breast_screening/tests/system/administrative/test_participant_record.py +++ b/manage_breast_screening/tests/system/administrative/test_participant_record.py @@ -27,7 +27,7 @@ def test_viewing_participant_record_from_an_appointment(self): self.given_i_am_logged_in_as_an_administrative_user() self.and_the_participant_has_an_upcoming_appointment() self.and_i_am_viewing_the_upcoming_appointment() - self.when_i_click_on_view_participant_record() + self.when_i_click_on_participant_details() self.then_i_should_be_on_the_participant_record_page() self.and_i_should_see_the_participant_record() self.when_i_click_on_the_back_link() @@ -36,25 +36,9 @@ def test_viewing_participant_record_from_an_appointment(self): def test_accessibility(self): self.given_i_am_logged_in_as_an_administrative_user() self.and_the_participant_has_an_upcoming_appointment() - self.and_i_am_on_the_participant_record_page() + self.and_i_am_on_the_participant_details_tab() self.then_the_accessibility_baseline_is_met() - def test_viewing_upcoming_appointments(self): - self.given_i_am_logged_in_as_an_administrative_user() - self.and_the_participant_has_an_upcoming_appointment() - self.and_i_am_on_the_participant_record_page() - self.then_i_should_see_the_upcoming_appointment() - self.when_i_click_on_the_upcoming_appointment() - self.then_i_should_be_on_the_upcoming_appointment_page() - - def test_viewing_past_appointments(self): - self.given_i_am_logged_in_as_an_administrative_user() - self.and_the_participant_has_past_appointments() - self.and_i_am_on_the_participant_record_page() - self.then_i_should_see_the_past_appointments() - self.when_i_click_on_a_past_appointment() - self.then_i_should_be_on_the_past_appointment_page() - def and_the_participant_has_an_upcoming_appointment(self): clinic_slot = ClinicSlotFactory( starts_at=datetime(2025, 1, 2, 11, tzinfo=tz.utc), @@ -95,18 +79,16 @@ def and_i_am_viewing_the_upcoming_appointment(self): ) ) - def and_i_am_on_the_participant_record_page(self): + def and_i_am_on_the_participant_details_tab(self): self.page.goto( self.live_server_url + reverse( - "participants:show", - kwargs={"pk": self.participant.pk}, + "mammograms:participant_details", + kwargs={"pk": self.upcoming_appointment.pk}, ) ) - and_i_am_on_the_participant_record_page = and_i_am_on_the_participant_record_page - - def when_i_click_on_view_participant_record(self): + def when_i_click_on_participant_details(self): self.page.get_by_role("link", name="Participant details").click() def then_i_should_be_on_the_participant_record_page(self):