Merge pull request #70 from sartography/test-production-519

Test production #519
This commit is contained in:
Dan Funk 2021-11-10 15:44:03 -05:00 committed by GitHub
commit c4cc89cd1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 64 deletions

View File

@ -0,0 +1,26 @@
"""empty message
Revision ID: d6627c76ed75
Revises: 42d973f2723f
Create Date: 2021-11-08 13:53:51.020066
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd6627c76ed75'
down_revision = '42d973f2723f'
branch_labels = None
depends_on = None
def upgrade():
op.execute('ALTER TABLE required_document RENAME COLUMN "AUXDOC" TO "AUXILIARY_DOC"')
op.execute('ALTER TABLE required_document RENAME COLUMN "AUXDOCID" TO "SS_AUXILIARY_DOC_TYPE_ID"')
def downgrade():
op.execute('ALTER TABLE required_document RENAME COLUMN "AUXILIARY_DOC" TO "AUXDOC"')
op.execute('ALTER TABLE required_document RENAME COLUMN "SS_AUXILIARY_DOC_TYPE_ID" TO "AUXDOCID"')

View File

@ -27,7 +27,7 @@ def sponsors(studyid):
def get_study_details(studyid):
details = session.query(StudyDetails).filter(StudyDetails.STUDYID == studyid).first()
return StudyDetailsSchema().dump(details)
return [StudyDetailsSchema().dump(details)]
def check_study(studyid):

View File

@ -14,7 +14,7 @@ class StudyForm(FlaskForm):
NETBADGEID = StringField('User UVA Computing Id', [validators.DataRequired()])
requirements = SelectMultipleField("Documents",
render_kw={'class': 'multi'},
choices=[(rd.AUXDOCID, rd.AUXDOC) for rd in RequiredDocument.all()])
choices=[(rd.SS_AUXILIARY_DOC_TYPE_ID, rd.AUXILIARY_DOC) for rd in RequiredDocument.all()])
Q_COMPLETE = SelectField("IRBStatus",
choices=[((q.STATUS, q.DETAIL), q.DETAIL) for q in IRBStatus.all()])
@ -150,8 +150,8 @@ class ConfirmDeleteForm(FlaskForm):
class RequirementsTable(Table):
AUXDOCID = Col('Code')
AUXDOC = Col('Name')
SS_AUXILIARY_DOC_TYPE_ID = Col('Code')
AUXILIARY_DOC = Col('Name')
class InvestigatorsTable(Table):

View File

@ -2,7 +2,7 @@ from marshmallow import fields
from sqlalchemy import func
from pb import db, ma
from marshmallow_sqlalchemy import SQLAlchemySchema
from sqlalchemy.orm import backref
from sqlalchemy.orm import backref, dynamic
class Sponsor(db.Model):
@ -75,13 +75,10 @@ class Study(db.Model):
investigators = db.relationship("Investigator", backref="study", lazy='dynamic')
study_details = db.relationship("StudyDetails", uselist=False, backref="study")
sponsors = db.relationship("StudySponsor", back_populates="study", cascade="all, delete, delete-orphan")
class StudySchema(ma.Schema):
class Meta:
# Fields to expose
fields = ("STUDYID", "TITLE", "NETBADGEID",
"DATE_MODIFIED")
# This is a hack to get PB Mock up and running
# We need to decide what to do about HSRNUMBER
# TODO: Resolve HSRNUMBER issue
HSRNUMBER = "0"
class IRBInfoEvent(db.Model):
@ -207,64 +204,88 @@ class Investigator(db.Model):
class InvestigatorSchema(ma.Schema):
class Meta:
fields = ("NETBADGEID", "INVESTIGATORTYPE", "INVESTIGATORTYPEFULL")
fields = ("STUDYID", "NETBADGEID", "INVESTIGATORTYPE", "INVESTIGATORTYPEFULL")
class RequiredDocument(db.Model):
id = db.Column(db.Integer, primary_key=True)
AUXDOCID = db.Column(db.String(), nullable=False, default="")
AUXDOC = db.Column(db.String(), nullable=False, default="")
SS_AUXILIARY_DOC_TYPE_ID = db.Column(db.String(), nullable=False, default="")
AUXILIARY_DOC = db.Column(db.String(), nullable=False, default="")
STUDYID = db.Column(db.Integer, db.ForeignKey('study.STUDYID'))
@staticmethod
def all():
docs = [RequiredDocument(AUXDOCID=1, AUXDOC="Investigators Brochure"),
RequiredDocument(AUXDOCID=2, AUXDOC="Screening Log"),
RequiredDocument(AUXDOCID=3, AUXDOC="Protocol"),
RequiredDocument(AUXDOCID=6, AUXDOC="Cancer Center's PRC Approval Form"),
RequiredDocument(AUXDOCID=7, AUXDOC="GCRC Approval Form"),
RequiredDocument(AUXDOCID=8, AUXDOC="SOM CTO IND/IDE Review Letter"),
RequiredDocument(AUXDOCID=9, AUXDOC="HIRE Approval"),
RequiredDocument(AUXDOCID=10, AUXDOC="Cancer Center's PRC Approval Waiver"),
RequiredDocument(AUXDOCID=11, AUXDOC="HSR Grant"),
RequiredDocument(AUXDOCID=12, AUXDOC="Certificate of Confidentiality Application"),
RequiredDocument(AUXDOCID=14, AUXDOC="Institutional Biosafety Committee Approval"),
RequiredDocument(AUXDOCID=18, AUXDOC="SOM CTO Approval Letter - UVA PI Multisite Trial"),
RequiredDocument(AUXDOCID=19, AUXDOC="IRB Approval or Letter of Approval from Administration: Send Data or Specimens to UVA"),
RequiredDocument(AUXDOCID=20, AUXDOC="IRB Approval or Letter of Approval from Administration: Study Conducted at non- UVA Facilities "),
RequiredDocument(AUXDOCID=21, AUXDOC="New Medical Device Form"),
RequiredDocument(AUXDOCID=22, AUXDOC="SOM CTO Review regarding need for IDE"),
RequiredDocument(AUXDOCID=23, AUXDOC="SOM CTO Review regarding need for IND"),
RequiredDocument(AUXDOCID=24, AUXDOC="InfoSec Approval"),
RequiredDocument(AUXDOCID=25, AUXDOC="Scientific Pre-review Documentation"),
RequiredDocument(AUXDOCID=26, AUXDOC="IBC Number"),
RequiredDocument(AUXDOCID=32, AUXDOC="IDS - Investigational Drug Service Approval"),
RequiredDocument(AUXDOCID=33, AUXDOC="Data Security Plan"),
RequiredDocument(AUXDOCID=35, AUXDOC="Model Consent"),
RequiredDocument(AUXDOCID=36, AUXDOC="RDRC Approval "),
RequiredDocument(AUXDOCID=39, AUXDOC="Age of Majority Cover Letter and Consent"),
RequiredDocument(AUXDOCID=40, AUXDOC="SBS/IRB Approval-FERPA"),
RequiredDocument(AUXDOCID=41, AUXDOC="HIRE Standard Radiation Language"),
RequiredDocument(AUXDOCID=42, AUXDOC="COI Management Plan"),
RequiredDocument(AUXDOCID=43, AUXDOC="SOM CTO Approval Letter-Non UVA, Non Industry PI MultiSite Study"),
RequiredDocument(AUXDOCID=44, AUXDOC="GRIME Approval"),
RequiredDocument(AUXDOCID=45, AUXDOC="GMEC Approval"),
RequiredDocument(AUXDOCID=46, AUXDOC="IRB Reliance Agreement Request Form- IRB-HSR is IRB of Record"),
RequiredDocument(AUXDOCID=47, AUXDOC="Non UVA IRB Approval - Initial and Last Continuation"),
RequiredDocument(AUXDOCID=48, AUXDOC="MR Physicist Approval- Use of Gadolinium"),
RequiredDocument(AUXDOCID=49, AUXDOC="SOM CTO Approval- Non- UVA Academia PI of IDE"),
RequiredDocument(AUXDOCID=51, AUXDOC="IDS Waiver"),
RequiredDocument(AUXDOCID=52, AUXDOC="Package Inserts"),
RequiredDocument(AUXDOCID=53, AUXDOC="IRB Reliance Agreement Request Form- IRB-HSR Not IRB of Record"),
RequiredDocument(AUXDOCID=54, AUXDOC="ESCRO Approval"),
RequiredDocument(AUXDOCID=56, AUXDOC="Unaffiliated Investigator Agreement "),
RequiredDocument(AUXDOCID=57, AUXDOC="Laser Safety Officer Approval"),
RequiredDocument(AUXDOCID=58, AUXDOC="FDA Letter granting IND/IDE# or exemption")]
docs = [RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=1, AUXILIARY_DOC="Investigators Brochure"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=2, AUXILIARY_DOC="Screening Log"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=3, AUXILIARY_DOC="Protocol"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=6, AUXILIARY_DOC="Cancer Center's PRC Approval Form"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=7, AUXILIARY_DOC="GCRC Approval Form"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=8, AUXILIARY_DOC="SOM CTO IND/IDE Review Letter"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=9, AUXILIARY_DOC="HIRE Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=10, AUXILIARY_DOC="Cancer Center's PRC Approval Waiver"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=11, AUXILIARY_DOC="HSR Grant"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=12, AUXILIARY_DOC="Certificate of Confidentiality Application"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=14, AUXILIARY_DOC="Institutional Biosafety Committee Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=18, AUXILIARY_DOC="SOM CTO Approval Letter - UVA PI Multisite Trial"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=19, AUXILIARY_DOC="IRB Approval or Letter of Approval from Administration: Send Data or Specimens to UVA"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=20, AUXILIARY_DOC="IRB Approval or Letter of Approval from Administration: Study Conducted at non- UVA Facilities "),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=21, AUXILIARY_DOC="New Medical Device Form"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=22, AUXILIARY_DOC="SOM CTO Review regarding need for IDE"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=23, AUXILIARY_DOC="SOM CTO Review regarding need for IND"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=24, AUXILIARY_DOC="InfoSec Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=25, AUXILIARY_DOC="Scientific Pre-review Documentation"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=26, AUXILIARY_DOC="IBC Number"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=32, AUXILIARY_DOC="IDS - Investigational Drug Service Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=33, AUXILIARY_DOC="Data Security Plan"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=35, AUXILIARY_DOC="Model Consent"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=36, AUXILIARY_DOC="RDRC Approval "),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=39, AUXILIARY_DOC="Age of Majority Cover Letter and Consent"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=40, AUXILIARY_DOC="SBS/IRB Approval-FERPA"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=41, AUXILIARY_DOC="HIRE Standard Radiation Language"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=42, AUXILIARY_DOC="COI Management Plan"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=43, AUXILIARY_DOC="SOM CTO Approval Letter-Non UVA, Non Industry PI MultiSite Study"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=44, AUXILIARY_DOC="GRIME Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=45, AUXILIARY_DOC="GMEC Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=46, AUXILIARY_DOC="IRB Reliance Agreement Request Form- IRB-HSR is IRB of Record"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=47, AUXILIARY_DOC="Non UVA IRB Approval - Initial and Last Continuation"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=48, AUXILIARY_DOC="MR Physicist Approval- Use of Gadolinium"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=49, AUXILIARY_DOC="SOM CTO Approval- Non- UVA Academia PI of IDE"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=51, AUXILIARY_DOC="IDS Waiver"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=52, AUXILIARY_DOC="Package Inserts"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=53, AUXILIARY_DOC="IRB Reliance Agreement Request Form- IRB-HSR Not IRB of Record"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=54, AUXILIARY_DOC="ESCRO Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=56, AUXILIARY_DOC="Unaffiliated Investigator Agreement "),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=57, AUXILIARY_DOC="Laser Safety Officer Approval"),
RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=58, AUXILIARY_DOC="FDA Letter granting IND/IDE# or exemption")]
return docs
class RequiredDocumentSchema(ma.Schema):
class Meta:
fields = ("AUXDOCID", "AUXDOC")
i_aux_docs = []
include_relationships = True
load_instance = True
fields = ("AUXDOCS", "OTHERDOCS", "TEMPLATEDOCS")
# fields = ("SS_AUXILIARY_DOC_TYPE_ID", "AUXILIARY_DOC")
AUXDOCS = fields.Method("get_aux_docs")
OTHERDOCS = fields.Method("get_other_docs")
TEMPLATEDOCS = fields.Method("get_template_docs")
@staticmethod
def get_aux_docs(obj):
aux_docs = []
if obj is not None and hasattr(obj, 'AUXILIARY_DOC') and hasattr(obj, 'SS_AUXILIARY_DOC_TYPE_ID'):
aux_docs.append({'AUXILIARY_DOC': obj.AUXILIARY_DOC, 'SS_AUXILIARY_DOC_TYPE_ID': obj.SS_AUXILIARY_DOC_TYPE_ID})
return aux_docs
@staticmethod
def get_other_docs(obj):
return []
@staticmethod
def get_template_docs(obj):
return []
class IRBStatus(db.Model):
@ -285,6 +306,30 @@ class IRBStatusSchema(ma.Schema):
fields = ("STATUS", "DETAIL")
class StudySchema(ma.Schema):
class Meta:
include_relationships = True
load_instance = True
# Fields to expose
fields = ("STUDYID", "TITLE", "NETBADGEID",
"DATE_MODIFIED", "Q_COMPLETE", "HSRNUMBER")
Q_COMPLETE = fields.Method("get_q_complete")
# TODO: Resolve HSRNUMBER issue
# Currently, we set HSRNUMBER to 0 in the model
@staticmethod
def get_q_complete(obj):
"""Ultimately, this will be calculated based on the contents of Q_COMPLETE.
For now, we return the contents of Q_COMPLETE"""
# TODO: Calculate whatever we need to calculate.
# TODO: Currently, we don't return HSRNUMBER,
# but we don't currently use it in CR Connect either
if obj is not None and hasattr(obj, 'Q_COMPLETE'):
if len(obj.Q_COMPLETE.all()) > 0:
return {'STATUS': obj.Q_COMPLETE[0].STATUS, 'DETAIL': obj.Q_COMPLETE[0].DETAIL}
return {}
class StudyDetails(db.Model):
STUDYID = db.Column(db.Integer, db.ForeignKey('study.STUDYID'), primary_key=True)
UVA_STUDY_TRACKING = db.Column(db.String, nullable=True)

View File

@ -88,10 +88,10 @@ def _update_study(study, form):
for r in form.requirements:
if r.checked:
requirement = RequiredDocument(AUXDOCID=r.data, AUXDOC=r.label.text, study=study)
requirement = RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=r.data, AUXILIARY_DOC=r.label.text, study=study)
db.session.add(requirement)
if r.data == 39:
requirement_2 = RequiredDocument(AUXDOCID=39, AUXDOC='Consent-Age of Majority Cover Letter', study=study)
requirement_2 = RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID=39, AUXILIARY_DOC='Consent-Age of Majority Cover Letter', study=study)
db.session.add(requirement_2)
q_data = eval(form.Q_COMPLETE.data)
@ -236,7 +236,7 @@ def verify_required_document_list():
local = RequiredDocument.all()
local_documents_list = []
for loc in local:
local_documents_list.append({'AUXDOCID': loc.AUXDOCID, 'AUXDOC': loc.AUXDOC})
local_documents_list.append({'SS_AUXILIARY_DOC_TYPE_ID': loc.SS_AUXILIARY_DOC_TYPE_ID, 'AUXILIARY_DOC': loc.AUXILIARY_DOC})
required_documents_list = []
master_list = _get_required_document_list()
@ -244,14 +244,14 @@ def verify_required_document_list():
for doc in master_list:
doc['AUXILIARY_DOC'] = doc['AUXILIARY_DOC'].replace("\r", '')
doc['AUXILIARY_DOC'] = doc['AUXILIARY_DOC'].replace("\n", '')
required_documents_list.append({'AUXDOCID': doc['SS_AUXILIARY_DOC_TYPE'], 'AUXDOC': doc['AUXILIARY_DOC']})
required_documents_list.append({'SS_AUXILIARY_DOC_TYPE_ID': doc['SS_AUXILIARY_DOC_TYPE'], 'AUXILIARY_DOC': doc['AUXILIARY_DOC']})
verify = compare_the_lists(required_documents_list, local_documents_list)
if not verify:
# Printing this so it is easier to update the hardcoded list in models.RequiredDocument
to_print = '['
for rd in required_documents_list:
to_print += f"RequiredDocument(AUXDOCID={rd['AUXDOCID']}, AUXDOC=\"{rd['AUXDOC']}\"), "
to_print += f"RequiredDocument(SS_AUXILIARY_DOC_TYPE_ID={rd['SS_AUXILIARY_DOC_TYPE_ID']}, AUXILIARY_DOC=\"{rd['AUXILIARY_DOC']}\"), "
to_print += ']'
print(to_print)
return verify

View File

@ -84,7 +84,7 @@ def edit_study(study_id):
form = StudyForm(request.form, obj=study)
if request.method == 'GET':
if study.requirements:
form.requirements.data = list(map(lambda r: r.AUXDOCID, list(study.requirements)))
form.requirements.data = list(map(lambda r: r.SS_AUXILIARY_DOC_TYPE_ID, list(study.requirements)))
if study.Q_COMPLETE and study.Q_COMPLETE.first():
form.Q_COMPLETE.data = "('" + study.Q_COMPLETE.first().STATUS + "', '" + study.Q_COMPLETE.first().DETAIL + "')"
else: