diff --git a/applications/form_specs.py b/applications/form_specs.py index ccab1dd32a..622ae9f971 100644 --- a/applications/form_specs.py +++ b/applications/form_specs.py @@ -113,6 +113,11 @@ help_text=snippet("study_purpose-help_text"), template_name="form_textarea", ), + Field( + name="read_analytic_methods_policy", + label="Have all applicants for OpenSAFELY read and agree to the OpenSAFELY Analytic Methods Policy?", + help_text=snippet("read_analytic_methods_policy-help_text"), + ), ], ), ], diff --git a/applications/forms.py b/applications/forms.py index 969a89314f..19160d013e 100644 --- a/applications/forms.py +++ b/applications/forms.py @@ -12,6 +12,7 @@ def __init__(self, *args, **kwargs): # which uses choices. radio_fields = [ "all_applicants_completed_getting_started", + "read_analytic_methods_policy", "need_record_level_data", "is_approved", ] diff --git a/applications/migrations/0003_add_read_analytic_methods_policy.py b/applications/migrations/0003_add_read_analytic_methods_policy.py new file mode 100644 index 0000000000..b646ad5f48 --- /dev/null +++ b/applications/migrations/0003_add_read_analytic_methods_policy.py @@ -0,0 +1,20 @@ +# Generated by Django 5.0.7 on 2024-07-23 15:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("applications", "0002_add_short_data_report"), + ] + + operations = [ + migrations.AddField( + model_name="studyinformationpage", + name="read_analytic_methods_policy", + field=models.BooleanField( + choices=[(True, "Yes"), (False, "No")], null=True + ), + ), + ] diff --git a/applications/models.py b/applications/models.py index 027bb195d1..a504615a48 100644 --- a/applications/models.py +++ b/applications/models.py @@ -218,6 +218,9 @@ class CommercialInvolvementPage(AbstractPage): class StudyInformationPage(AbstractPage): study_name = models.TextField(blank=True) study_purpose = models.TextField(blank=True) + read_analytic_methods_policy = models.BooleanField( + null=True, choices=YES_NO_CHOICES + ) class StudyPurposePage(AbstractPage): diff --git a/snippets/read_analytic_methods_policy-help_text.md b/snippets/read_analytic_methods_policy-help_text.md new file mode 100644 index 0000000000..5fec9bdf34 --- /dev/null +++ b/snippets/read_analytic_methods_policy-help_text.md @@ -0,0 +1,3 @@ +The [OpenSAFELY Analytic Methods Policy][1] can be found on the OpenSAFELY website. + +[1]: https://www.opensafely.org/policies-for-researchers/#opensafely-analytic-methods-policy diff --git a/tests/factories/application.py b/tests/factories/application.py index d5e6828346..34f72fb920 100644 --- a/tests/factories/application.py +++ b/tests/factories/application.py @@ -75,6 +75,7 @@ class Meta: study_name = factory.Sequence(lambda n: f"study {n}") study_purpose = factory.Sequence(lambda n: f"purpose {n}") + read_analytic_methods_policy = factory.fuzzy.FuzzyChoice([True, False]) class StudyPurposePageFactory(AbstractPageFactory): diff --git a/tests/integration/test_applications.py b/tests/integration/test_applications.py index f0cb5666ba..c068838ebb 100644 --- a/tests/integration/test_applications.py +++ b/tests/integration/test_applications.py @@ -82,6 +82,7 @@ def test_successful_application(client, mailoutbox, slack_messages): data = { "study_name": "Title for this study", "study_purpose": "Long form technical message about what this study is about", + "read_analytic_methods_policy": "True", } response = client.post(url("study-information"), data, follow=True) assert response.status_code == 200