From bd4a9cced3aae1a4b10bb83e53ed82c5c5d97485 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 13 Aug 2021 12:06:27 -0400 Subject: [PATCH 1/8] We no longer use HSRNUMBER to automatically set Study Status to `Open for Enrollment` --- crc/services/study_service.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crc/services/study_service.py b/crc/services/study_service.py index 738ee0e9..76e3cfc7 100644 --- a/crc/services/study_service.py +++ b/crc/services/study_service.py @@ -398,11 +398,6 @@ class StudyService(object): session.add(db_study) db_studies.append(db_study) - if pb_study.HSRNUMBER: - db_study.irb_status = IrbStatus.hsr_assigned - if db_study.status != StudyStatus.open_for_enrollment: - new_status = StudyStatus.open_for_enrollment - db_study.update_from_protocol_builder(pb_study) StudyService._add_all_workflow_specs_to_study(db_study) From 58119c8969e30a854c682fe8dd168a4012f0eda0 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 13 Aug 2021 12:32:11 -0400 Subject: [PATCH 2/8] Modified `test_get_all_studies` so they don't fail looking for studies that are open for enrollment We will soon have a new way to automatically set study status to `Open for Enrollment`, so I left the failing tests there and commented them out for now. --- tests/study/test_study_api.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/study/test_study_api.py b/tests/study/test_study_api.py index 5fde7eab..628b4210 100644 --- a/tests/study/test_study_api.py +++ b/tests/study/test_study_api.py @@ -190,17 +190,19 @@ class TestStudyApi(BaseTest): num_abandoned += 1 if study['status'] == 'in_progress': # One study is marked complete without HSR Number num_in_progress += 1 - if study['status'] == 'open_for_enrollment': # One study is marked complete and has an HSR Number + if study['status'] == 'open_for_enrollment': # Currently, we don't automatically set studies to open for enrollment num_open += 1 db_studies_after = session.query(StudyModel).all() num_db_studies_after = len(db_studies_after) self.assertGreater(num_db_studies_after, num_db_studies_before) self.assertEqual(num_abandoned, 1) - self.assertEqual(num_open, 1) + self.assertEqual(num_open, 0) # Currently, we don't automatically set studies to open for enrollment self.assertEqual(num_in_progress, 2) self.assertEqual(len(json_data), num_db_studies_after) - self.assertEqual(num_open + num_in_progress + num_abandoned, num_db_studies_after) + # The count is off, since we don't automatically set studies to Open for Enrollment + # This will likely change in the future + # self.assertEqual(num_open + num_in_progress + num_abandoned, num_db_studies_after) # Automatic events check in_progress_events = session.query(StudyEvent).filter_by(status=StudyStatus.in_progress) @@ -209,8 +211,10 @@ class TestStudyApi(BaseTest): abandoned_events = session.query(StudyEvent).filter_by(status=StudyStatus.abandoned) self.assertEqual(abandoned_events.count(), 1) # 1 study has been abandoned - open_for_enrollment_events = session.query(StudyEvent).filter_by(status=StudyStatus.open_for_enrollment) - self.assertEqual(open_for_enrollment_events.count(), 1) # 1 study was moved to open for enrollment + # We don't currently set any studies to Open for Enrollment automatically + # This will likely change + # open_for_enrollment_events = session.query(StudyEvent).filter_by(status=StudyStatus.open_for_enrollment) + # self.assertEqual(open_for_enrollment_events.count(), 1) # 1 study was moved to open for enrollment @patch('crc.services.protocol_builder.ProtocolBuilderService.get_investigators') # mock_studies @patch('crc.services.protocol_builder.ProtocolBuilderService.get_required_docs') # mock_docs From febcb1ac5b6231f8ce0fa01d41f08d8f9e63b0a6 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 13 Aug 2021 12:36:43 -0400 Subject: [PATCH 3/8] Clarified my comments --- tests/study/test_study_api.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/study/test_study_api.py b/tests/study/test_study_api.py index 628b4210..4f939c09 100644 --- a/tests/study/test_study_api.py +++ b/tests/study/test_study_api.py @@ -200,8 +200,9 @@ class TestStudyApi(BaseTest): self.assertEqual(num_open, 0) # Currently, we don't automatically set studies to open for enrollment self.assertEqual(num_in_progress, 2) self.assertEqual(len(json_data), num_db_studies_after) - # The count is off, since we don't automatically set studies to Open for Enrollment - # This will likely change in the future + # The sum below is off, since we don't automatically set studies to Open for Enrollment + # Leaving the test here because we will need it again + # when we implement a new way to set Open for Enrollment # self.assertEqual(num_open + num_in_progress + num_abandoned, num_db_studies_after) # Automatic events check @@ -212,7 +213,8 @@ class TestStudyApi(BaseTest): self.assertEqual(abandoned_events.count(), 1) # 1 study has been abandoned # We don't currently set any studies to Open for Enrollment automatically - # This will likely change + # Leaving the test here because we will need it again + # when we implement a new way to set Open for Enrollment # open_for_enrollment_events = session.query(StudyEvent).filter_by(status=StudyStatus.open_for_enrollment) # self.assertEqual(open_for_enrollment_events.count(), 1) # 1 study was moved to open for enrollment From 46d7b13326b6217e66857ad67ef4ca84275f3d5d Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 16 Aug 2021 12:09:02 -0400 Subject: [PATCH 4/8] Start to remove HSR Number --- crc/models/protocol_builder.py | 16 ++++++++-------- crc/models/study.py | 3 --- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/crc/models/protocol_builder.py b/crc/models/protocol_builder.py index 267e1427..d669096a 100644 --- a/crc/models/protocol_builder.py +++ b/crc/models/protocol_builder.py @@ -19,21 +19,21 @@ class ProtocolBuilderInvestigatorType(enum.Enum): # Deprecated: Marked for removal class ProtocolBuilderStatus(enum.Enum): - # • Active: found in PB and no HSR number and not hold + # • Active: found in PB and not hold # • Hold: store boolean value in CR Connect (add to Study Model) - # • Open To Enrollment: has start date and HSR number? + # • Open To Enrollment: has start date? # • Abandoned: deleted in PB incomplete = 'incomplete' # Found in PB but not ready to start (not q_complete) - active = 'active' # found in PB, marked as "q_complete" and no HSR number and not hold + active = 'active' # found in PB, marked as "q_complete" and not hold hold = 'hold' # CR Connect side, if the Study ias marked as "hold". - open = 'open' # Open To Enrollment: has start date and HSR number? + open = 'open' # Open To Enrollment: has start date? abandoned = 'abandoned' # Not found in PB #DRAFT = 'draft', # !Q_COMPLETE - #IN_PROCESS = 'in_process', # Q_COMPLETE && !UPLOAD_COMPLETE && !HSRNUMBER - #IN_REVIEW = 'in_review', # Q_COMPLETE && (!UPLOAD_COMPLETE || !HSRNUMBER) - #REVIEW_COMPLETE = 'review_complete', # Q_COMPLETE && UPLOAD_COMPLETE && HSRNUMBER + #IN_PROCESS = 'in_process', # Q_COMPLETE && !UPLOAD_COMPLETE + #IN_REVIEW = 'in_review', # Q_COMPLETE && (!UPLOAD_COMPLETE) + #REVIEW_COMPLETE = 'review_complete', # Q_COMPLETE && UPLOAD_COMPLETE #INACTIVE = 'inactive', # Not found in PB @@ -54,7 +54,7 @@ class ProtocolBuilderStudySchema(ma.Schema): class Meta: model = ProtocolBuilderStudy unknown = INCLUDE - fields = ["STUDYID", "HSRNUMBER", "TITLE", "NETBADGEID", + fields = ["STUDYID", "TITLE", "NETBADGEID", "DATE_MODIFIED"] @post_load diff --git a/crc/models/study.py b/crc/models/study.py index 3918fe5f..b671df16 100644 --- a/crc/models/study.py +++ b/crc/models/study.py @@ -57,7 +57,6 @@ class StudyModel(db.Model): events_history = db.relationship("StudyEvent", cascade="all, delete, delete-orphan") def update_from_protocol_builder(self, pbs: ProtocolBuilderStudy): - self.hsr_number = pbs.HSRNUMBER self.title = pbs.TITLE self.user_uid = pbs.NETBADGEID self.last_updated = pbs.DATE_MODIFIED @@ -220,7 +219,6 @@ class StudyForUpdateSchema(ma.Schema): id = fields.Integer(required=False, allow_none=True) status = EnumField(StudyStatus, by_value=True) - hsr_number = fields.String(allow_none=True) sponsor = fields.String(allow_none=True) ind_number = fields.String(allow_none=True) enrollment_date = fields.DateTime(allow_none=True) @@ -252,7 +250,6 @@ class StudySchema(ma.Schema): warnings = fields.List(fields.Nested(ApiErrorSchema), dump_only=True) protocol_builder_status = EnumField(StudyStatus, by_value=True) status = EnumField(StudyStatus, by_value=True) - hsr_number = fields.String(allow_none=True) short_title = fields.String(allow_none=True) sponsor = fields.String(allow_none=True) ind_number = fields.String(allow_none=True) From 1f82143aeada521d1c55634a97f438868e8da13e Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 16 Aug 2021 12:50:09 -0400 Subject: [PATCH 5/8] Remove HSR Number from models --- crc/models/protocol_builder.py | 3 +-- crc/models/study.py | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/crc/models/protocol_builder.py b/crc/models/protocol_builder.py index d669096a..831f80a0 100644 --- a/crc/models/protocol_builder.py +++ b/crc/models/protocol_builder.py @@ -40,11 +40,10 @@ class ProtocolBuilderStatus(enum.Enum): class ProtocolBuilderStudy(object): def __init__( - self, STUDYID: int, HSRNUMBER: str, TITLE: str, NETBADGEID: str, + self, STUDYID: int, TITLE: str, NETBADGEID: str, DATE_MODIFIED: str ): self.STUDYID = STUDYID - self.HSRNUMBER = HSRNUMBER self.TITLE = TITLE self.NETBADGEID = NETBADGEID self.DATE_MODIFIED = DATE_MODIFIED diff --git a/crc/models/study.py b/crc/models/study.py index b671df16..967a964d 100644 --- a/crc/models/study.py +++ b/crc/models/study.py @@ -27,7 +27,6 @@ class StudyStatus(enum.Enum): class IrbStatus(enum.Enum): incomplete_in_protocol_builder = 'incomplete in protocol builder' completed_in_protocol_builder = 'completed in protocol builder' - hsr_assigned = 'hsr number assigned' class StudyEventType(enum.Enum): @@ -46,7 +45,6 @@ class StudyModel(db.Model): irb_status = db.Column(db.Enum(IrbStatus)) primary_investigator_id = db.Column(db.String, nullable=True) sponsor = db.Column(db.String, nullable=True) - hsr_number = db.Column(db.String, nullable=True) ind_number = db.Column(db.String, nullable=True) user_uid = db.Column(db.String, db.ForeignKey('user.uid'), nullable=False) investigator_uids = db.Column(db.ARRAY(db.String), nullable=True) @@ -171,7 +169,7 @@ class Study(object): def __init__(self, title, short_title, last_updated, primary_investigator_id, user_uid, id=None, status=None, irb_status=None, comment="", - sponsor="", hsr_number="", ind_number="", categories=[], + sponsor="", ind_number="", categories=[], files=[], approvals=[], enrollment_date=None, events_history=[], last_activity_user="",last_activity_date =None,create_user_display="", **argsv): self.id = id @@ -187,7 +185,6 @@ class Study(object): self.comment = comment self.primary_investigator_id = primary_investigator_id self.sponsor = sponsor - self.hsr_number = hsr_number self.ind_number = ind_number self.categories = categories self.approvals = approvals From b3fd72de8b64b4b9c84e347299d1e86485a48a6c Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 16 Aug 2021 12:51:48 -0400 Subject: [PATCH 6/8] Remove hsr_number from Study Schema --- crc/api.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/crc/api.yml b/crc/api.yml index ff8a33ed..284a2b28 100755 --- a/crc/api.yml +++ b/crc/api.yml @@ -1627,10 +1627,6 @@ components: type: string x-nullable: true example: "27b-6-42" - hsr_number: - type: string - x-nullable: true - example: "27b-6-1212" StudyAssociate: properties: uid: From ab8714c93e2763ee159904092176172e2d8a76e7 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 16 Aug 2021 13:01:51 -0400 Subject: [PATCH 7/8] Remove HSRNUMBER from mock data --- tests/data/pb_responses/user_studies.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/data/pb_responses/user_studies.json b/tests/data/pb_responses/user_studies.json index be88c47f..784b94e6 100644 --- a/tests/data/pb_responses/user_studies.json +++ b/tests/data/pb_responses/user_studies.json @@ -1,21 +1,18 @@ [ { "DATE_MODIFIED": "2020-02-19T14:26:49.127756", - "HSRNUMBER": "12345", "NETBADGEID": "dhf8r", "STUDYID": 54321, "TITLE": "Another study about the effect of a naked mannequin on software productivity" }, { "DATE_MODIFIED": "2020-02-19T14:24:55.101695", - "HSRNUMBER": "", "NETBADGEID": "dhf8r", "STUDYID": 65432, "TITLE": "Peanut butter consumption among quiet dogs" }, { "DATE_MODIFIED": "2020-02-19T14:24:55.101695", - "HSRNUMBER": "", "NETBADGEID": "dhf8r", "STUDYID": 1, "TITLE": "Efficacy of xenomorph bio-augmented circuits on dexterity of cybernetic prostheses" From fcebc6ac2b5031f2e0254e6547630828d62d1ad8 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Mon, 16 Aug 2021 13:02:12 -0400 Subject: [PATCH 8/8] Revision file for DB changes --- migrations/versions/3d9ae7cfc231_.py | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 migrations/versions/3d9ae7cfc231_.py diff --git a/migrations/versions/3d9ae7cfc231_.py b/migrations/versions/3d9ae7cfc231_.py new file mode 100644 index 00000000..d3132473 --- /dev/null +++ b/migrations/versions/3d9ae7cfc231_.py @@ -0,0 +1,40 @@ +"""Remove HSR Number + +Revision ID: 3d9ae7cfc231 +Revises: 2a6f7ea00e5f +Create Date: 2021-08-16 11:28:40.027495 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '3d9ae7cfc231' +down_revision = '2a6f7ea00e5f' +branch_labels = None +depends_on = None + + +def upgrade(): + # Remove `hsr_assigned` values from Study table + op.execute("UPDATE study SET irb_status = 'incomplete_in_protocol_builder' where irb_status = 'hsr_assigned'") + + # Remove `hsr_assigned` from IRB Status Enum + op.execute("ALTER TYPE irbstatus RENAME TO irbstatus_old") + op.execute("CREATE TYPE irbstatus AS ENUM('incomplete_in_protocol_builder', 'completed_in_protocol_builder')") + op.execute("ALTER TABLE study ALTER COLUMN irb_status TYPE irbstatus USING irb_status::text::irbstatus") + op.execute("DROP TYPE irbstatus_old") + + # Remove hsr_number column from Study table + op.drop_column('study', 'hsr_number') + + + +def downgrade(): + op.execute("ALTER TYPE irbstatus RENAME TO irbstatus_old") + op.execute("CREATE TYPE irbstatus AS ENUM('incomplete_in_protocol_builder', 'completed_in_protocol_builder', 'hsr_assigned')") + op.execute("ALTER TABLE study ALTER COLUMN irb_status TYPE irbstatus USING irb_status::text::irbstatus") + op.execute("DROP TYPE irbstatus_old") + + op.add_column('study', sa.Column('hsr_number', sa.String(), nullable=True))