diff --git a/crc/scripts/get_study_status.py b/crc/scripts/get_study_status.py
new file mode 100644
index 00000000..8bc34fcb
--- /dev/null
+++ b/crc/scripts/get_study_status.py
@@ -0,0 +1,18 @@
+from crc import session
+from crc.models.study import StudyModel
+from crc.scripts.script import Script
+
+
+class GetStudyStatus(Script):
+
+ def get_description(self):
+ return """Get the status of the current study.
+ Status can be one of `in_progress`, `hold`, `open_for_enrollment`, or `abandoned`."""
+
+ def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
+ return self.do_task(task, study_id, workflow_id, *args, **kwargs)
+
+ def do_task(self, task, study_id, workflow_id, *args, **kwargs):
+ study_status = session.query(StudyModel.status).filter(StudyModel.id == study_id).scalar()
+ if study_status:
+ return study_status.value
diff --git a/crc/scripts/set_study_status.py b/crc/scripts/set_study_status.py
new file mode 100644
index 00000000..32397d0c
--- /dev/null
+++ b/crc/scripts/set_study_status.py
@@ -0,0 +1,69 @@
+from crc import session
+from crc.api.common import ApiError
+from crc.models.study import StudyModel, StudyStatus
+from crc.scripts.script import Script
+
+
+class SetStudyStatus(Script):
+
+ def get_description(self):
+ return """Set the status of the current study.
+ Status can be one of `in_progress`, `hold`, `open_for_enrollment`, or `abandoned`."""
+
+ def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
+
+ if 'new_status' in kwargs.keys() or len(args) > 0:
+ if 'new_status' in kwargs.keys():
+ new_status = kwargs['new_status']
+ else:
+ new_status = args[0]
+
+ try:
+ study_status = getattr(StudyStatus, new_status)
+
+ except AttributeError as ae:
+ raise ApiError.from_task(code='invalid_argument',
+ message=f"We could not find a status matching `{new_status}`. Original message: {ae}",
+ task=task)
+ return study_status.value
+
+ else:
+ raise ApiError.from_task(code='missing_argument',
+ message='You must include the new status when calling `set_study_status` script. '
+ 'The new status must be one of `in_progress`, `hold`, `open_for_enrollment`, or `abandoned`.',
+ task=task)
+
+ def do_task(self, task, study_id, workflow_id, *args, **kwargs):
+
+ # Get new status
+ if 'new_status' in kwargs.keys() or len(args) > 0:
+ if 'new_status' in kwargs.keys():
+ new_status = kwargs['new_status']
+ else:
+ new_status = args[0]
+
+ # Get StudyStatus object for new_status
+ try:
+ study_status = getattr(StudyStatus, new_status)
+
+ # Invalid argument
+ except AttributeError as ae:
+ raise ApiError.from_task(code='invalid_argument',
+ message=f"We could not find a status matching `{new_status}`. Original message: {ae}"
+ 'The new status must be one of `in_progress`, `hold`, `open_for_enrollment`, or `abandoned`.',
+ task=task)
+
+ # Set new status
+ study_model = session.query(StudyModel).filter(StudyModel.id == study_id).first()
+ study_model.status = study_status
+ session.commit()
+
+ return study_model.status.value
+
+ # Missing argument
+ else:
+ raise ApiError.from_task(code='missing_argument',
+ message='You must include the new status when calling `set_study_status` script. '
+ 'The new status must be one of `in_progress`, `hold`, `open_for_enrollment`, or `abandoned`.',
+ task=task)
+
diff --git a/tests/data/get_study_status/get_study_status.bpmn b/tests/data/get_study_status/get_study_status.bpmn
new file mode 100644
index 00000000..760814db
--- /dev/null
+++ b/tests/data/get_study_status/get_study_status.bpmn
@@ -0,0 +1,47 @@
+
+
+
+
+ Flow_1iqprcz
+
+
+
+ Flow_1iqprcz
+ Flow_0npc38l
+ study_status = get_study_status()
+
+
+ # Study Status
+{{ study_status }}
+ Flow_0npc38l
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/set_study_status/set_study_status.bpmn b/tests/data/set_study_status/set_study_status.bpmn
new file mode 100644
index 00000000..af1027d3
--- /dev/null
+++ b/tests/data/set_study_status/set_study_status.bpmn
@@ -0,0 +1,114 @@
+
+
+
+
+ Flow_0c77bdh
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Flow_1e9oiuw
+ Flow_0q0rtvj
+
+
+
+ Flow_0q0rtvj
+ Flow_0ana8xt
+ returned_status = set_study_status(selected_status)
+
+
+
+ # Study Status
+
+## Original Status
+{{ original_status }}
+
+## Selected Status
+{{ selected_status }}
+
+## Returned Status
+{{ returned_status }}
+
+
+## New Status
+{{ new_status }}
+ Flow_0nckhhn
+ Flow_14s6jnt
+
+
+ Flow_14s6jnt
+
+
+
+
+
+ Flow_0c77bdh
+ Flow_1e9oiuw
+ original_status = get_study_status()
+
+
+
+ Flow_0ana8xt
+ Flow_0nckhhn
+ new_status = get_study_status()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/scripts/test_get_study_status.py b/tests/scripts/test_get_study_status.py
new file mode 100644
index 00000000..8012ddb7
--- /dev/null
+++ b/tests/scripts/test_get_study_status.py
@@ -0,0 +1,11 @@
+from tests.base_test import BaseTest
+
+
+class TestGetStudyStatus(BaseTest):
+
+ def test_get_study_status(self):
+ workflow = self.create_workflow('get_study_status')
+ workflow_api = self.get_workflow_api(workflow)
+ task = workflow_api.next_task
+
+ self.assertEqual(task.data['study_status'], workflow.study.status.value)
diff --git a/tests/scripts/test_set_study_status.py b/tests/scripts/test_set_study_status.py
new file mode 100644
index 00000000..ece8c30c
--- /dev/null
+++ b/tests/scripts/test_set_study_status.py
@@ -0,0 +1,35 @@
+from tests.base_test import BaseTest
+
+
+class TestSetStudyStatus(BaseTest):
+
+ def test_set_study_status_validation(self):
+ self.load_example_data()
+ spec_model = self.load_test_spec('set_study_status')
+ rv = self.app.get('/v1.0/workflow-specification/%s/validate' % spec_model.id, headers=self.logged_in_headers())
+ self.assertEqual([], rv.json)
+
+ def test_set_study_status(self):
+ workflow = self.create_workflow('set_study_status')
+ workflow_api = self.get_workflow_api(workflow)
+ task = workflow_api.next_task
+
+ original_status = task.data['original_status']
+ self.assertEqual('in_progress', original_status)
+
+ workflow_api = self.complete_form(workflow, task, {'selected_status': 'hold'})
+ task = workflow_api.next_task
+
+ self.assertEqual('Activity_DisplayStatus', task.name)
+ self.assertEqual('hold', task.data['selected_status'])
+ self.assertEqual('hold', task.data['new_status'])
+
+ def test_set_study_status_fail(self):
+
+ self.load_example_data()
+ workflow = self.create_workflow('set_study_status')
+ workflow_api = self.get_workflow_api(workflow)
+ task = workflow_api.next_task
+
+ with self.assertRaises(AssertionError):
+ self.complete_form(workflow, task, {'selected_status': 'asdf'})