Let GP surgeries create their own organisations

We have a bunch of GP surgeries who want to go live. They don’t
automatically assigned to organisations. So this means a lot of back and
forth to get these organisations set up, and then the service has to
re-request to go live, and… it’s painful.

Instead, let’s let GPs create their own organisations, by confirming the
name of their organisation before going on to letting them accept the
agreement.
This commit is contained in:
Chris Hill-Scott
2019-09-04 16:27:25 +01:00
parent d41effe8ce
commit daeefefeaa
7 changed files with 156 additions and 0 deletions

View File

@@ -13,6 +13,12 @@ from app.utils import user_has_permissions
@main.route('/services/<uuid:service_id>/agreement')
@user_has_permissions('manage_service')
def service_agreement(service_id):
if (
current_service.organisation_type == 'nhs_gp' and not current_service.organisation
):
return redirect(
url_for('main.add_organisation_from_gp_service', service_id=current_service.id)
)
if current_service.organisation.crown is None:
return render_template('views/agreement/service-agreement-choose.html')
if current_service.organisation.agreement_signed:

View File

@@ -7,6 +7,7 @@ from werkzeug.exceptions import abort
from app import (
current_organisation,
current_service,
email_branding_client,
letter_branding_client,
org_invite_api_client,
@@ -63,6 +64,36 @@ def add_organisation():
)
@main.route('/services/<uuid:service_id>/add-gp-organisation', methods=['GET', 'POST'])
@user_has_permissions('manage_service')
def add_organisation_from_gp_service(service_id):
print(current_service.organisation_type)
print(current_service.organisation)
if (not current_service.organisation_type == 'nhs_gp') or current_service.organisation:
abort(403)
form = RenameOrganisationForm()
if form.validate_on_submit():
Organisation.create(
form.name.data,
crown=False,
organisation_type='nhs_gp',
agreement_signed=False,
).associate_service(
service_id
)
return redirect(url_for(
'.service_agreement',
service_id=service_id,
))
return render_template(
'views/organisations/add-gp-organisation.html',
form=form
)
@main.route("/organisations/<org_id>", methods=['GET'])
@user_has_permissions()
def organisation_dashboard(org_id):

View File

@@ -152,6 +152,12 @@ class Organisation(JSONModel):
response = organisations_client.update_organisation(self.id, **kwargs)
self.__init__(response)
def associate_service(self, service_id):
organisations_client.update_service_organisation(
str(service_id),
self.id
)
class Organisations(ModelList):
client = organisations_client.get_organisations

View File

@@ -123,6 +123,7 @@ class HeaderNavigation(Navigation):
'action_blocked',
'add_data_retention',
'add_organisation',
'add_organisation_from_gp_service',
'add_service',
'add_service_template',
'api_callbacks',
@@ -379,6 +380,7 @@ class MainNavigation(Navigation):
'usage',
},
'settings': {
'add_organisation_from_gp_service',
'branding_request',
'estimate_usage',
'link_service_to_organisation',
@@ -633,6 +635,7 @@ class CaseworkNavigation(Navigation):
'action_blocked',
'add_data_retention',
'add_organisation',
'add_organisation_from_gp_service',
'add_service',
'add_service_template',
'api_callbacks',
@@ -926,6 +929,7 @@ class OrgNavigation(Navigation):
'action_blocked',
'add_data_retention',
'add_organisation',
'add_organisation_from_gp_service',
'add_service',
'add_service_template',
'api_callbacks',

View File

@@ -0,0 +1,18 @@
{% extends "withnav_template.html" %}
{% from "components/page-header.html" import page_header %}
{% from "components/page-footer.html" import page_footer %}
{% from "components/textbox.html" import textbox %}
{% from "components/radios.html" import radios %}
{% from "components/form.html" import form_wrapper %}
{% block per_page_title %}
What is the name of your organisation?
{% endblock %}
{% block maincolumn_content %}
{{ page_header('What is the name of your organisation?') }}
{% call form_wrapper() %}
{{textbox(form.name)}}
{{ page_footer('Continue') }}
{% endcall %}
{% endblock %}

View File

@@ -160,6 +160,75 @@ def test_create_new_organisation_validates(
assert mock_create_organisation.called is False
@pytest.mark.parametrize('organisation_type, organisation, expected_status', (
('nhs_gp', None, 200),
('central', None, 403),
('nhs_gp', organisation_json(organisation_type='nhs_gp'), 403),
))
def test_only_gps_can_create_own_organisations(
client_request,
mocker,
service_one,
organisation_type,
organisation,
expected_status,
):
mocker.patch('app.organisations_client.get_service_organisation', return_value=organisation)
service_one['organisation_type'] = organisation_type
page = client_request.get(
'.add_organisation_from_gp_service',
service_id=SERVICE_ONE_ID,
_expected_status=expected_status,
)
if expected_status == 403:
return
assert page.select_one('input[type=text]')['name'] == 'name'
assert normalize_spaces(
page.select_one('label[for=name]').text
) == (
'Whats your practice called?'
)
def test_gps_can_name_their_organisation(
client_request,
mocker,
service_one,
mock_update_service_organisation,
):
mocker.patch('app.organisations_client.get_service_organisation', return_value=None)
service_one['organisation_type'] = 'nhs_gp'
mock_create_organisation = mocker.patch(
'app.organisations_client.create_organisation',
return_value=organisation_json(ORGANISATION_ID),
)
client_request.post(
'.add_organisation_from_gp_service',
service_id=SERVICE_ONE_ID,
_data={
'name': 'Dr. Example',
},
_expected_status=302,
_expected_redirect=url_for(
'main.service_agreement',
service_id=SERVICE_ONE_ID,
_external=True,
)
)
mock_create_organisation.assert_called_once_with(
name='Dr. Example',
organisation_type='nhs_gp',
agreement_signed=False,
crown=False,
)
mock_update_service_organisation.assert_called_once_with(SERVICE_ONE_ID, ORGANISATION_ID)
def test_organisation_services_shows_live_services_only(
client_request,
mock_get_organisation,

View File

@@ -108,6 +108,28 @@ def test_show_agreement_page(
assert link['href'] == url()
def test_unknown_gps_are_redirected(
client_request,
mocker,
fake_uuid,
mock_has_jobs,
service_one,
):
mocker.patch('app.organisations_client.get_service_organisation', return_value=None)
service_one['organisation_id'] = None
service_one['organisation_type'] = 'nhs_gp'
client_request.get(
'main.service_agreement',
service_id=SERVICE_ONE_ID,
_expected_status=302,
_expected_redirect=url_for(
'main.add_organisation_from_gp_service',
service_id=SERVICE_ONE_ID,
_external=True,
),
)
@pytest.mark.parametrize('crown, expected_status, expected_file_fetched, expected_file_served', (
(
True, 200, 'crown.pdf',