Merge pull request #357 from sartography/426-remove-hsr-number
remove hsr number #426
This commit is contained in:
commit
c831ee7e4a
|
@ -1627,10 +1627,6 @@ components:
|
||||||
type: string
|
type: string
|
||||||
x-nullable: true
|
x-nullable: true
|
||||||
example: "27b-6-42"
|
example: "27b-6-42"
|
||||||
hsr_number:
|
|
||||||
type: string
|
|
||||||
x-nullable: true
|
|
||||||
example: "27b-6-1212"
|
|
||||||
StudyAssociate:
|
StudyAssociate:
|
||||||
properties:
|
properties:
|
||||||
uid:
|
uid:
|
||||||
|
|
|
@ -19,32 +19,31 @@ class ProtocolBuilderInvestigatorType(enum.Enum):
|
||||||
|
|
||||||
# Deprecated: Marked for removal
|
# Deprecated: Marked for removal
|
||||||
class ProtocolBuilderStatus(enum.Enum):
|
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)
|
# • 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
|
# • Abandoned: deleted in PB
|
||||||
incomplete = 'incomplete' # Found in PB but not ready to start (not q_complete)
|
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".
|
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
|
abandoned = 'abandoned' # Not found in PB
|
||||||
|
|
||||||
|
|
||||||
#DRAFT = 'draft', # !Q_COMPLETE
|
#DRAFT = 'draft', # !Q_COMPLETE
|
||||||
#IN_PROCESS = 'in_process', # Q_COMPLETE && !UPLOAD_COMPLETE && !HSRNUMBER
|
#IN_PROCESS = 'in_process', # Q_COMPLETE && !UPLOAD_COMPLETE
|
||||||
#IN_REVIEW = 'in_review', # Q_COMPLETE && (!UPLOAD_COMPLETE || !HSRNUMBER)
|
#IN_REVIEW = 'in_review', # Q_COMPLETE && (!UPLOAD_COMPLETE)
|
||||||
#REVIEW_COMPLETE = 'review_complete', # Q_COMPLETE && UPLOAD_COMPLETE && HSRNUMBER
|
#REVIEW_COMPLETE = 'review_complete', # Q_COMPLETE && UPLOAD_COMPLETE
|
||||||
#INACTIVE = 'inactive', # Not found in PB
|
#INACTIVE = 'inactive', # Not found in PB
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProtocolBuilderStudy(object):
|
class ProtocolBuilderStudy(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, STUDYID: int, HSRNUMBER: str, TITLE: str, NETBADGEID: str,
|
self, STUDYID: int, TITLE: str, NETBADGEID: str,
|
||||||
DATE_MODIFIED: str
|
DATE_MODIFIED: str
|
||||||
):
|
):
|
||||||
self.STUDYID = STUDYID
|
self.STUDYID = STUDYID
|
||||||
self.HSRNUMBER = HSRNUMBER
|
|
||||||
self.TITLE = TITLE
|
self.TITLE = TITLE
|
||||||
self.NETBADGEID = NETBADGEID
|
self.NETBADGEID = NETBADGEID
|
||||||
self.DATE_MODIFIED = DATE_MODIFIED
|
self.DATE_MODIFIED = DATE_MODIFIED
|
||||||
|
@ -54,7 +53,7 @@ class ProtocolBuilderStudySchema(ma.Schema):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProtocolBuilderStudy
|
model = ProtocolBuilderStudy
|
||||||
unknown = INCLUDE
|
unknown = INCLUDE
|
||||||
fields = ["STUDYID", "HSRNUMBER", "TITLE", "NETBADGEID",
|
fields = ["STUDYID", "TITLE", "NETBADGEID",
|
||||||
"DATE_MODIFIED"]
|
"DATE_MODIFIED"]
|
||||||
|
|
||||||
@post_load
|
@post_load
|
||||||
|
|
|
@ -27,7 +27,6 @@ class StudyStatus(enum.Enum):
|
||||||
class IrbStatus(enum.Enum):
|
class IrbStatus(enum.Enum):
|
||||||
incomplete_in_protocol_builder = 'incomplete in protocol builder'
|
incomplete_in_protocol_builder = 'incomplete in protocol builder'
|
||||||
completed_in_protocol_builder = 'completed in protocol builder'
|
completed_in_protocol_builder = 'completed in protocol builder'
|
||||||
hsr_assigned = 'hsr number assigned'
|
|
||||||
|
|
||||||
|
|
||||||
class StudyEventType(enum.Enum):
|
class StudyEventType(enum.Enum):
|
||||||
|
@ -46,7 +45,6 @@ class StudyModel(db.Model):
|
||||||
irb_status = db.Column(db.Enum(IrbStatus))
|
irb_status = db.Column(db.Enum(IrbStatus))
|
||||||
primary_investigator_id = db.Column(db.String, nullable=True)
|
primary_investigator_id = db.Column(db.String, nullable=True)
|
||||||
sponsor = 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)
|
ind_number = db.Column(db.String, nullable=True)
|
||||||
user_uid = db.Column(db.String, db.ForeignKey('user.uid'), nullable=False)
|
user_uid = db.Column(db.String, db.ForeignKey('user.uid'), nullable=False)
|
||||||
investigator_uids = db.Column(db.ARRAY(db.String), nullable=True)
|
investigator_uids = db.Column(db.ARRAY(db.String), nullable=True)
|
||||||
|
@ -57,7 +55,6 @@ class StudyModel(db.Model):
|
||||||
events_history = db.relationship("StudyEvent", cascade="all, delete, delete-orphan")
|
events_history = db.relationship("StudyEvent", cascade="all, delete, delete-orphan")
|
||||||
|
|
||||||
def update_from_protocol_builder(self, pbs: ProtocolBuilderStudy):
|
def update_from_protocol_builder(self, pbs: ProtocolBuilderStudy):
|
||||||
self.hsr_number = pbs.HSRNUMBER
|
|
||||||
self.title = pbs.TITLE
|
self.title = pbs.TITLE
|
||||||
self.user_uid = pbs.NETBADGEID
|
self.user_uid = pbs.NETBADGEID
|
||||||
self.last_updated = pbs.DATE_MODIFIED
|
self.last_updated = pbs.DATE_MODIFIED
|
||||||
|
@ -172,7 +169,7 @@ class Study(object):
|
||||||
|
|
||||||
def __init__(self, title, short_title, last_updated, primary_investigator_id, user_uid,
|
def __init__(self, title, short_title, last_updated, primary_investigator_id, user_uid,
|
||||||
id=None, status=None, irb_status=None, comment="",
|
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=[],
|
files=[], approvals=[], enrollment_date=None, events_history=[],
|
||||||
last_activity_user="",last_activity_date =None,create_user_display="", **argsv):
|
last_activity_user="",last_activity_date =None,create_user_display="", **argsv):
|
||||||
self.id = id
|
self.id = id
|
||||||
|
@ -188,7 +185,6 @@ class Study(object):
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
self.primary_investigator_id = primary_investigator_id
|
self.primary_investigator_id = primary_investigator_id
|
||||||
self.sponsor = sponsor
|
self.sponsor = sponsor
|
||||||
self.hsr_number = hsr_number
|
|
||||||
self.ind_number = ind_number
|
self.ind_number = ind_number
|
||||||
self.categories = categories
|
self.categories = categories
|
||||||
self.approvals = approvals
|
self.approvals = approvals
|
||||||
|
@ -220,7 +216,6 @@ class StudyForUpdateSchema(ma.Schema):
|
||||||
|
|
||||||
id = fields.Integer(required=False, allow_none=True)
|
id = fields.Integer(required=False, allow_none=True)
|
||||||
status = EnumField(StudyStatus, by_value=True)
|
status = EnumField(StudyStatus, by_value=True)
|
||||||
hsr_number = fields.String(allow_none=True)
|
|
||||||
sponsor = fields.String(allow_none=True)
|
sponsor = fields.String(allow_none=True)
|
||||||
ind_number = fields.String(allow_none=True)
|
ind_number = fields.String(allow_none=True)
|
||||||
enrollment_date = fields.DateTime(allow_none=True)
|
enrollment_date = fields.DateTime(allow_none=True)
|
||||||
|
@ -252,7 +247,6 @@ class StudySchema(ma.Schema):
|
||||||
warnings = fields.List(fields.Nested(ApiErrorSchema), dump_only=True)
|
warnings = fields.List(fields.Nested(ApiErrorSchema), dump_only=True)
|
||||||
protocol_builder_status = EnumField(StudyStatus, by_value=True)
|
protocol_builder_status = EnumField(StudyStatus, by_value=True)
|
||||||
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)
|
short_title = fields.String(allow_none=True)
|
||||||
sponsor = fields.String(allow_none=True)
|
sponsor = fields.String(allow_none=True)
|
||||||
ind_number = fields.String(allow_none=True)
|
ind_number = fields.String(allow_none=True)
|
||||||
|
|
|
@ -398,11 +398,6 @@ class StudyService(object):
|
||||||
session.add(db_study)
|
session.add(db_study)
|
||||||
db_studies.append(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)
|
db_study.update_from_protocol_builder(pb_study)
|
||||||
StudyService._add_all_workflow_specs_to_study(db_study)
|
StudyService._add_all_workflow_specs_to_study(db_study)
|
||||||
|
|
||||||
|
|
|
@ -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))
|
|
@ -1,21 +1,18 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"DATE_MODIFIED": "2020-02-19T14:26:49.127756",
|
"DATE_MODIFIED": "2020-02-19T14:26:49.127756",
|
||||||
"HSRNUMBER": "12345",
|
|
||||||
"NETBADGEID": "dhf8r",
|
"NETBADGEID": "dhf8r",
|
||||||
"STUDYID": 54321,
|
"STUDYID": 54321,
|
||||||
"TITLE": "Another study about the effect of a naked mannequin on software productivity"
|
"TITLE": "Another study about the effect of a naked mannequin on software productivity"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
||||||
"HSRNUMBER": "",
|
|
||||||
"NETBADGEID": "dhf8r",
|
"NETBADGEID": "dhf8r",
|
||||||
"STUDYID": 65432,
|
"STUDYID": 65432,
|
||||||
"TITLE": "Peanut butter consumption among quiet dogs"
|
"TITLE": "Peanut butter consumption among quiet dogs"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
||||||
"HSRNUMBER": "",
|
|
||||||
"NETBADGEID": "dhf8r",
|
"NETBADGEID": "dhf8r",
|
||||||
"STUDYID": 1,
|
"STUDYID": 1,
|
||||||
"TITLE": "Efficacy of xenomorph bio-augmented circuits on dexterity of cybernetic prostheses"
|
"TITLE": "Efficacy of xenomorph bio-augmented circuits on dexterity of cybernetic prostheses"
|
||||||
|
|
|
@ -190,17 +190,20 @@ class TestStudyApi(BaseTest):
|
||||||
num_abandoned += 1
|
num_abandoned += 1
|
||||||
if study['status'] == 'in_progress': # One study is marked complete without HSR Number
|
if study['status'] == 'in_progress': # One study is marked complete without HSR Number
|
||||||
num_in_progress += 1
|
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
|
num_open += 1
|
||||||
|
|
||||||
db_studies_after = session.query(StudyModel).all()
|
db_studies_after = session.query(StudyModel).all()
|
||||||
num_db_studies_after = len(db_studies_after)
|
num_db_studies_after = len(db_studies_after)
|
||||||
self.assertGreater(num_db_studies_after, num_db_studies_before)
|
self.assertGreater(num_db_studies_after, num_db_studies_before)
|
||||||
self.assertEqual(num_abandoned, 1)
|
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(num_in_progress, 2)
|
||||||
self.assertEqual(len(json_data), num_db_studies_after)
|
self.assertEqual(len(json_data), num_db_studies_after)
|
||||||
self.assertEqual(num_open + num_in_progress + num_abandoned, num_db_studies_after)
|
# 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
|
# Automatic events check
|
||||||
in_progress_events = session.query(StudyEvent).filter_by(status=StudyStatus.in_progress)
|
in_progress_events = session.query(StudyEvent).filter_by(status=StudyStatus.in_progress)
|
||||||
|
@ -209,8 +212,11 @@ class TestStudyApi(BaseTest):
|
||||||
abandoned_events = session.query(StudyEvent).filter_by(status=StudyStatus.abandoned)
|
abandoned_events = session.query(StudyEvent).filter_by(status=StudyStatus.abandoned)
|
||||||
self.assertEqual(abandoned_events.count(), 1) # 1 study has been 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)
|
# We don't currently set any studies to Open for Enrollment automatically
|
||||||
self.assertEqual(open_for_enrollment_events.count(), 1) # 1 study was moved 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
|
||||||
|
# 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_investigators') # mock_studies
|
||||||
@patch('crc.services.protocol_builder.ProtocolBuilderService.get_required_docs') # mock_docs
|
@patch('crc.services.protocol_builder.ProtocolBuilderService.get_required_docs') # mock_docs
|
||||||
|
|
Loading…
Reference in New Issue