Merge pull request #49 from sartography/irb-api-endpoints-273

Irb api endpoints #273
This commit is contained in:
Dan Funk 2021-04-08 12:44:48 -04:00 committed by GitHub
commit 128945d0b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 14 deletions

View File

@ -0,0 +1,33 @@
"""empty message
Revision ID: 119c1269ee7c
Revises: 93a1e2ce38dc
Create Date: 2021-03-31 12:30:19.645458
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '119c1269ee7c'
down_revision = '93a1e2ce38dc'
branch_labels = None
depends_on = None
def upgrade():
op.drop_column('study', 'Q_COMPLETE')
op.create_table('irb_status',
sa.Column('STUDYID', sa.Integer(), nullable=False),
sa.Column('STATUS', sa.String(), nullable=False, default=''),
sa.Column('DETAIL', sa.String(), nullable=False, default=''),
sa.ForeignKeyConstraint(['STUDYID'], ['study.STUDYID'],),
sa.PrimaryKeyConstraint('STUDYID')
)
def downgrade():
op.drop_table('irb_status')
op.add_column('study', sa.Column('Q_COMPLETE', sa.Boolean(), nullable=True))

View File

@ -41,6 +41,11 @@ def sponsors(studyid):
return StudySponsorSchema(many=True).dump(sponsors)
def check_study(studyid):
irb_status = db.session.query(IRBStatus).filter(IRBStatus.STUDYID == studyid).first()
return IRBStatusSchema().dump(irb_status)
def get_form(id, requirement_code):
return
@ -157,7 +162,7 @@ def site_map():
# **************************
from pb.forms import StudyForm, StudyTable, InvestigatorForm, StudyDetailsForm, ConfirmDeleteForm, StudySponsorForm
from pb.models import Study, RequiredDocument, Investigator, StudySchema, RequiredDocumentSchema, InvestigatorSchema, \
StudyDetails, StudyDetailsSchema, StudySponsor, Sponsor, SponsorSchema, StudySponsorSchema
StudyDetails, StudyDetailsSchema, StudySponsor, Sponsor, SponsorSchema, StudySponsorSchema, IRBStatus, IRBStatusSchema
from pb.ldap.ldap_service import LdapService
@ -201,6 +206,8 @@ def new_study():
flash('Study created successfully!', 'success')
return redirect_home()
# set default first time
form.Q_COMPLETE.data = "('No Error', 'Passed validation.')"
return render_template(
'form.html',
form=form,
@ -220,8 +227,10 @@ def edit_study(study_id):
title = "Edit Study #" + study_id
if study.requirements:
form.requirements.data = list(map(lambda r: r.AUXDOCID, list(study.requirements)))
if study.Q_COMPLETE:
form.Q_COMPLETE.checked = True
if study.Q_COMPLETE and study.Q_COMPLETE.first():
form.Q_COMPLETE.data = "('" + study.Q_COMPLETE.first().STATUS + "', '" + study.Q_COMPLETE.first().DETAIL + "')"
else:
form.Q_COMPLETE.data = "('No Error', 'Passed validation.')"
if request.method == 'POST':
_update_study(study, form)
flash('Study updated successfully!', 'success')
@ -441,7 +450,6 @@ def _update_study(study, form):
study.TITLE = form.TITLE.data
study.NETBADGEID = form.NETBADGEID.data
study.DATE_MODIFIED = datetime.datetime.now()
study.Q_COMPLETE = form.Q_COMPLETE.data
study.HSRNUMBER = form.HSRNUMBER.data
for r in form.requirements:
@ -449,6 +457,18 @@ def _update_study(study, form):
requirement = RequiredDocument(AUXDOCID=r.data, AUXDOC=r.label.text, study=study)
db.session.add(requirement)
q_data = eval(form.Q_COMPLETE.data)
if q_data:
q_data_status = q_data[0]
q_data_detail = q_data[1]
q_status = db.session.query(IRBStatus).filter(IRBStatus.STUDYID == study.STUDYID).first()
if q_status:
q_status.STATUS = q_data_status
q_status.DETAIL = q_data_detail
else:
q_status = IRBStatus(STATUS=q_data_status, DETAIL=q_data_detail, STUDYID=study.STUDYID)
db.session.add(q_status)
db.session.add(study)
db.session.commit()

View File

@ -133,6 +133,27 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/StudyDetail"
/check_study/{studyid}:
parameters:
- name: studyid
in: path
required: true
description: The id of the study.
schema:
type: integer
format: int32
get:
tags:
- CR-Connect
operationId: pb.check_study
summary: IRB Status about a particular study.
responses:
200:
description: Details about the protocol
content:
application/json:
schema:
$ref: "#/components/schemas/IRBStatus"
components:
schemas:
Study:
@ -156,11 +177,6 @@ components:
format: string
example: jfg6n
description: The UVA Id of of the principle investigator for the study.
Q_COMPLETE:
type: number
enum: [0,1]
example: 0
description: If 1, then this study is complete in the Protocol Builder, and is ready for processing by CR Connect.
DATE_MODIFIED:
type: string
format: date_time
@ -233,6 +249,21 @@ components:
type: string
example: Principal Investigator
description: A human readable descriptive string of the INVESTIGATORTYPE.
IRBStatus:
type: object
properties:
STUDYID:
type: number
example: 12345
description: The study id from the Protocol Builder
STATUS:
type: string
example: No Error
description: The study status
DETAIL:
type: string
example: Passed Validation
description: Detail about the study status
StudyDetail:
type: object
properties:

View File

@ -3,7 +3,7 @@ from flask_wtf import FlaskForm
from wtforms import SelectMultipleField, StringField, BooleanField, SelectField, validators, HiddenField
from wtforms_alchemy import ModelForm
from pb.models import RequiredDocument, Investigator, StudyDetails
from pb.models import RequiredDocument, Investigator, StudyDetails, IRBStatus
class StudyForm(FlaskForm):
@ -14,8 +14,8 @@ class StudyForm(FlaskForm):
render_kw={'class': 'multi'},
choices=[(rd.AUXDOCID, rd.AUXDOC) for rd in RequiredDocument.all()])
HSRNUMBER = StringField('HSR Number')
Q_COMPLETE = BooleanField('Complete in Protocol Builder?', default='checked',
false_values=(False, 'false', 0, '0'))
Q_COMPLETE = SelectField("IRBStatus",
choices=[((q.STATUS, q.DETAIL), q.DETAIL) for q in IRBStatus.all()])
class InvestigatorForm(FlaskForm):

View File

@ -67,8 +67,8 @@ class Study(db.Model):
HSRNUMBER = db.Column(db.String())
TITLE = db.Column(db.Text(), nullable=False)
NETBADGEID = db.Column(db.String(), nullable=False)
Q_COMPLETE = db.Column(db.Boolean, nullable=True)
DATE_MODIFIED = db.Column(db.DateTime(timezone=True), default=func.now())
Q_COMPLETE = db.relationship("IRBStatus", backref="study", lazy='dynamic')
requirements = db.relationship("RequiredDocument", backref="study", lazy='dynamic')
investigators = db.relationship("Investigator", backref="study", lazy='dynamic')
study_details = db.relationship("StudyDetails", uselist=False, backref="study")
@ -79,7 +79,7 @@ class StudySchema(ma.Schema):
class Meta:
# Fields to expose
fields = ("STUDYID", "HSRNUMBER", "TITLE", "NETBADGEID",
"Q_COMPLETE", "DATE_MODIFIED")
"DATE_MODIFIED")
class Investigator(db.Model):
@ -163,6 +163,24 @@ class RequiredDocumentSchema(ma.Schema):
fields = ("AUXDOCID", "AUXDOC")
class IRBStatus(db.Model):
STUDYID = db.Column(db.Integer, db.ForeignKey('study.STUDYID'), primary_key=True)
STATUS = db.Column(db.String(), nullable=False, default="")
DETAIL = db.Column(db.String(), nullable=False, default="")
@staticmethod
def all():
status = [IRBStatus(STATUS="Error", DETAIL="Study ID does not exist."),
IRBStatus(STATUS="Error", DETAIL="General study errors. UVA Study Tracking Number is missing or not formatted correctly."),
IRBStatus(STATUS="No Error", DETAIL="Passed validation.")]
return status
class IRBStatusSchema(ma.Schema):
class Meta:
fields = ("STATUS", "DETAIL")
class StudyDetails(db.Model):
STUDYID = db.Column(db.Integer, db.ForeignKey('study.STUDYID'), primary_key=True)
IS_IND = db.Column(db.Integer, nullable=True)

View File

@ -57,6 +57,8 @@ class Sanity_Check_Test(unittest.TestCase):
for r in form.requirements:
form.data['requirements'].append(r.data)
form.Q_COMPLETE.data = "('No Error', 'Passed validation.')"
r = self.app.post('/new_study', data=form.data, follow_redirects=False)
assert r.status_code == 302
added_study = Study.query.filter(Study.TITLE == study_title).first()
@ -79,6 +81,7 @@ class Sanity_Check_Test(unittest.TestCase):
for r in form_2.requirements:
form_2.data['requirements'].append(r.data)
form_2.Q_COMPLETE.data = "('No Error', 'Passed validation.')"
r_2 = self.app.post('/study/%i' % added_study.STUDYID, data=form_2.data, follow_redirects=False)
assert r_2.status_code == 302