2020-02-17 11:43:26 -05:00
|
|
|
import datetime
|
2020-03-23 13:57:19 -04:00
|
|
|
import os
|
2020-05-23 21:58:58 -04:00
|
|
|
import re
|
2020-05-25 15:21:29 -04:00
|
|
|
import yaml
|
2020-02-17 11:43:26 -05:00
|
|
|
from datetime import date
|
|
|
|
|
2020-01-08 15:57:00 -05:00
|
|
|
import connexion
|
2020-05-25 15:21:29 -04:00
|
|
|
from flask_cors import CORS
|
2020-02-14 15:19:30 -05:00
|
|
|
from flask import url_for, json, redirect, render_template, request, flash
|
2020-02-26 12:17:37 -05:00
|
|
|
from flask_assets import Environment, Bundle
|
2020-02-17 16:21:18 -05:00
|
|
|
from flask_sqlalchemy import SQLAlchemy
|
|
|
|
from flask_marshmallow import Marshmallow
|
2020-02-17 11:43:26 -05:00
|
|
|
from flask_migrate import Migrate
|
2020-03-24 16:52:13 -04:00
|
|
|
from sqlalchemy import func
|
2020-01-08 15:57:00 -05:00
|
|
|
|
|
|
|
PROTOCOLS = {}
|
|
|
|
|
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
def get_user_studies(uva_id):
|
|
|
|
studies = db.session.query(Study).filter(Study.NETBADGEID == uva_id).all()
|
|
|
|
return StudySchema(many=True).dump(studies)
|
2020-01-08 15:57:00 -05:00
|
|
|
|
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
def required_docs(studyid):
|
|
|
|
docs = db.session.query(RequiredDocument).filter(RequiredDocument.STUDYID == studyid).all()
|
|
|
|
return RequiredDocumentSchema(many=True).dump(docs)
|
2020-01-08 15:57:00 -05:00
|
|
|
|
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
def investigators(studyid):
|
|
|
|
inv = db.session.query(Investigator).filter(Investigator.STUDYID == studyid).all()
|
|
|
|
return InvestigatorSchema(many=True).dump(inv)
|
|
|
|
|
|
|
|
|
|
|
|
def get_study_details(studyid):
|
|
|
|
details = db.session.query(StudyDetails).filter(StudyDetails.STUDYID == studyid).first()
|
|
|
|
return StudyDetailsSchema().dump(details)
|
|
|
|
|
2020-01-08 15:57:00 -05:00
|
|
|
|
2020-02-11 14:50:32 -05:00
|
|
|
def get_form(id, requirement_code):
|
|
|
|
return
|
|
|
|
|
2020-05-25 15:21:29 -04:00
|
|
|
connexion_app = connexion.FlaskApp('Protocol Builder', specification_dir='pb')
|
|
|
|
app = connexion_app.app
|
2020-01-08 15:57:00 -05:00
|
|
|
|
2020-03-23 13:57:19 -04:00
|
|
|
app.config.from_object('config.default')
|
|
|
|
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
|
|
|
|
|
|
|
if "TESTING" in os.environ and os.environ["TESTING"] == "true":
|
|
|
|
app.config.from_object('config.testing')
|
2020-03-23 17:05:34 -04:00
|
|
|
app.config.from_pyfile('config/testing.py')
|
2020-03-23 13:57:19 -04:00
|
|
|
else:
|
|
|
|
app.config.root_path = app.instance_path
|
|
|
|
app.config.from_pyfile('config.py', silent=True)
|
|
|
|
|
2020-05-25 15:21:29 -04:00
|
|
|
connexion_app.add_api('api.yml', base_path='/v2.0')
|
|
|
|
|
|
|
|
# Convert list of allowed origins to list of regexes
|
|
|
|
origins_re = [r"^https?:\/\/%s(.*)" % o.replace('.', '\.') for o in app.config['CORS_ALLOW_ORIGINS']]
|
|
|
|
cors = CORS(connexion_app.app, origins=origins_re)
|
|
|
|
|
2020-02-14 15:19:30 -05:00
|
|
|
db = SQLAlchemy(app)
|
2020-08-12 19:15:16 -04:00
|
|
|
""":type: sqlalchemy.orm.SQLAlchemy"""
|
|
|
|
|
|
|
|
session = db.session
|
|
|
|
""":type: sqlalchemy.orm.Session"""
|
|
|
|
|
2020-02-17 11:43:26 -05:00
|
|
|
migrate = Migrate(app, db)
|
2020-02-17 16:21:18 -05:00
|
|
|
ma = Marshmallow(app)
|
2020-05-24 23:05:57 -04:00
|
|
|
|
|
|
|
# Set the path of the static directory
|
|
|
|
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
APP_STATIC = os.path.join(APP_ROOT, 'static')
|
|
|
|
BASE_HREF = app.config['APPLICATION_ROOT'].strip('/')
|
|
|
|
app.static_folder = APP_STATIC
|
|
|
|
app.static_url_path = app.config['APPLICATION_ROOT'] + 'static'
|
|
|
|
|
|
|
|
print('app.static_folder', app.static_folder)
|
|
|
|
print('app.static_url_path', app.static_url_path)
|
|
|
|
|
|
|
|
# remove old static map
|
|
|
|
url_map = app.url_map
|
|
|
|
try:
|
|
|
|
for rule in url_map.iter_rules('static'):
|
|
|
|
url_map._rules.remove(rule)
|
|
|
|
except ValueError:
|
|
|
|
# no static view was created yet
|
|
|
|
pass
|
|
|
|
|
|
|
|
# register new; the same view function is used
|
|
|
|
app.add_url_rule(
|
|
|
|
app.static_url_path + '/<path:filename>',
|
|
|
|
endpoint='static', view_func=app.send_static_file)
|
|
|
|
|
2020-02-26 12:17:37 -05:00
|
|
|
assets = Environment(app)
|
2020-05-24 23:05:57 -04:00
|
|
|
assets.init_app(app)
|
2020-02-26 12:17:37 -05:00
|
|
|
assets.url = app.static_url_path
|
2020-05-24 23:05:57 -04:00
|
|
|
scss = Bundle(
|
|
|
|
'scss/app.scss',
|
|
|
|
filters='pyscss',
|
|
|
|
output='app.css'
|
|
|
|
)
|
2020-02-26 12:17:37 -05:00
|
|
|
assets.register('app_scss', scss)
|
2020-02-17 16:21:18 -05:00
|
|
|
|
2020-02-18 09:25:29 -05:00
|
|
|
# Loads all the descriptions from the API so we can display them in the editor.
|
2020-02-17 16:21:18 -05:00
|
|
|
description_map = {}
|
2020-05-24 18:30:57 -04:00
|
|
|
with open(r'pb/api.yml') as file:
|
2020-02-17 16:21:18 -05:00
|
|
|
api_config = yaml.load(file, Loader=yaml.FullLoader)
|
|
|
|
study_detail_properties = api_config['components']['schemas']['StudyDetail']['properties']
|
|
|
|
for schema in api_config['components']['schemas']:
|
|
|
|
for field, values in api_config['components']['schemas'][schema]['properties'].items():
|
|
|
|
description_map[field] = values['description']
|
2020-01-08 15:57:00 -05:00
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
|
|
|
|
# **************************
|
|
|
|
# API ENDPOINTS
|
|
|
|
# **************************
|
2020-01-08 15:57:00 -05:00
|
|
|
def has_no_empty_params(rule):
|
|
|
|
defaults = rule.defaults if rule.defaults is not None else ()
|
|
|
|
arguments = rule.arguments if rule.arguments is not None else ()
|
|
|
|
return len(defaults) >= len(arguments)
|
|
|
|
|
2020-04-17 11:27:12 -04:00
|
|
|
|
2020-08-12 19:15:16 -04:00
|
|
|
@app.cli.command()
|
|
|
|
def load_example_data():
|
|
|
|
"""Load example data into the database."""
|
|
|
|
from example_data import ExampleDataLoader
|
|
|
|
ExampleDataLoader().clean_db()
|
|
|
|
ExampleDataLoader().load_all()
|
|
|
|
|
|
|
|
|
|
|
|
@app.cli.command()
|
|
|
|
def load_example_sponsors():
|
|
|
|
"""Load example data into the database."""
|
|
|
|
from example_data import ExampleDataLoader
|
|
|
|
ExampleDataLoader().load_sponsors()
|
|
|
|
|
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/site_map')
|
2020-01-08 15:57:00 -05:00
|
|
|
def site_map():
|
|
|
|
links = []
|
2020-02-14 15:19:30 -05:00
|
|
|
for rule in app.url_map.iter_rules():
|
2020-01-08 15:57:00 -05:00
|
|
|
# Filter out rules we can't navigate to in a browser
|
|
|
|
# and rules that require parameters
|
|
|
|
if "GET" in rule.methods and has_no_empty_params(rule):
|
2020-05-24 23:05:57 -04:00
|
|
|
url = app.confg['APPLICATION_ROOT'].strip('/') + url_for(rule.endpoint, **(rule.defaults or {}))
|
2020-01-08 15:57:00 -05:00
|
|
|
links.append((url, rule.endpoint))
|
|
|
|
return json.dumps({"links": links})
|
|
|
|
|
2020-01-08 16:05:16 -05:00
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
# **************************
|
|
|
|
# WEB FORMS
|
|
|
|
# **************************
|
2020-08-12 19:15:16 -04:00
|
|
|
from pb.forms import StudyForm, StudyTable, InvestigatorForm, StudyDetailsForm, ConfirmDeleteForm, StudySponsorForm
|
2020-05-24 18:30:57 -04:00
|
|
|
from pb.models import Study, RequiredDocument, Investigator, StudySchema, RequiredDocumentSchema, InvestigatorSchema, \
|
2020-08-12 19:15:16 -04:00
|
|
|
StudyDetails, StudyDetailsSchema, StudySponsor, Sponsor
|
2020-02-17 11:43:26 -05:00
|
|
|
|
2020-02-14 15:19:30 -05:00
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/', methods=['GET', 'POST'])
|
2020-02-14 15:19:30 -05:00
|
|
|
def index():
|
2020-02-17 11:43:26 -05:00
|
|
|
# display results
|
2020-02-17 16:21:18 -05:00
|
|
|
studies = db.session.query(Study).order_by(Study.DATE_MODIFIED.desc()).all()
|
2020-02-17 11:43:26 -05:00
|
|
|
table = StudyTable(studies)
|
2020-05-24 23:05:57 -04:00
|
|
|
return render_template(
|
|
|
|
'index.html',
|
|
|
|
table=table,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
2020-02-14 15:19:30 -05:00
|
|
|
|
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/new_study', methods=['GET', 'POST'])
|
2020-02-14 15:19:30 -05:00
|
|
|
def new_study():
|
|
|
|
form = StudyForm(request.form)
|
2020-05-24 23:05:57 -04:00
|
|
|
action = BASE_HREF + "/new_study"
|
2020-02-17 13:25:14 -05:00
|
|
|
title = "New Study"
|
2020-02-14 15:19:30 -05:00
|
|
|
if request.method == 'POST':
|
|
|
|
study = Study()
|
2020-02-17 16:21:18 -05:00
|
|
|
study.study_details = StudyDetails()
|
2020-02-17 11:43:26 -05:00
|
|
|
_update_study(study, form)
|
2020-06-30 14:48:11 -04:00
|
|
|
flash('Study created successfully!', 'success')
|
2020-05-24 23:05:57 -04:00
|
|
|
return redirect_home()
|
2020-02-14 15:19:30 -05:00
|
|
|
|
2020-05-24 23:05:57 -04:00
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
description_map=description_map,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
2020-02-14 15:19:30 -05:00
|
|
|
|
2020-04-17 11:27:12 -04:00
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/study/<study_id>', methods=['GET', 'POST'])
|
2020-02-17 11:43:26 -05:00
|
|
|
def edit_study(study_id):
|
2020-02-17 16:21:18 -05:00
|
|
|
study = db.session.query(Study).filter(Study.STUDYID == study_id).first()
|
2020-02-17 11:43:26 -05:00
|
|
|
form = StudyForm(request.form, obj=study)
|
|
|
|
if request.method == 'GET':
|
2020-05-24 23:05:57 -04:00
|
|
|
action = BASE_HREF + "/study/" + study_id
|
2020-02-17 13:25:14 -05:00
|
|
|
title = "Edit Study #" + study_id
|
2020-02-17 11:43:26 -05:00
|
|
|
if study.requirements:
|
2020-02-17 16:21:18 -05:00
|
|
|
form.requirements.data = list(map(lambda r: r.AUXDOCID, list(study.requirements)))
|
|
|
|
if study.Q_COMPLETE:
|
|
|
|
form.Q_COMPLETE.checked = True
|
2020-02-17 11:43:26 -05:00
|
|
|
if request.method == 'POST':
|
|
|
|
_update_study(study, form)
|
2020-06-30 14:48:11 -04:00
|
|
|
flash('Study updated successfully!', 'success')
|
2020-05-24 23:05:57 -04:00
|
|
|
return redirect_home()
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
description_map={},
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
2020-02-17 13:25:14 -05:00
|
|
|
|
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/investigator/<study_id>', methods=['GET', 'POST'])
|
2020-02-17 13:25:14 -05:00
|
|
|
def new_investigator(study_id):
|
|
|
|
form = InvestigatorForm(request.form)
|
2020-05-24 23:05:57 -04:00
|
|
|
action = BASE_HREF + "/investigator/" + study_id
|
2020-02-17 13:25:14 -05:00
|
|
|
title = "Add Investigator to Study " + study_id
|
|
|
|
if request.method == 'POST':
|
2020-02-17 16:21:18 -05:00
|
|
|
investigator = Investigator(STUDYID=study_id)
|
|
|
|
investigator.NETBADGEID = form.NETBADGEID.data
|
|
|
|
investigator.set_type(form.INVESTIGATORTYPE.data)
|
2020-02-17 13:25:14 -05:00
|
|
|
db.session.add(investigator)
|
|
|
|
db.session.commit()
|
2020-06-30 14:48:11 -04:00
|
|
|
flash('Investigator created successfully!', 'success')
|
2020-05-24 23:05:57 -04:00
|
|
|
return redirect_home()
|
2020-02-17 13:25:14 -05:00
|
|
|
|
2020-05-24 23:05:57 -04:00
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
description_map={},
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
2020-02-17 13:25:14 -05:00
|
|
|
|
|
|
|
|
2020-06-30 14:48:11 -04:00
|
|
|
@app.route('/del_investigator/<inv_id>', methods=['GET', 'POST'])
|
2020-02-17 13:25:14 -05:00
|
|
|
def del_investigator(inv_id):
|
2020-06-30 14:48:11 -04:00
|
|
|
inv_id = int(inv_id)
|
|
|
|
inv_model = db.session.query(Investigator).filter(Investigator.id == inv_id).first()
|
|
|
|
if inv_model is None:
|
|
|
|
flash('Investigator not found.', 'warn')
|
|
|
|
return redirect_home()
|
|
|
|
|
|
|
|
uid = inv_model.NETBADGEID
|
|
|
|
study_id = int(inv_model.STUDYID)
|
|
|
|
form = ConfirmDeleteForm(request.form, obj=inv_model)
|
|
|
|
|
|
|
|
if request.method == 'GET':
|
|
|
|
action = BASE_HREF + "/del_investigator/%i" % inv_id
|
|
|
|
title = "Delete Investigator #%i?" % inv_id
|
|
|
|
details = "Are you sure you want to delete Investigator '%s' from Study %i?" % (uid, study_id)
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
details=details,
|
|
|
|
description_map=description_map,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
if form.confirm and form.confirm.data:
|
|
|
|
db.session.query(Investigator).filter(Investigator.id == inv_id).delete()
|
|
|
|
db.session.commit()
|
|
|
|
flash('Investigator %s deleted from Study %i.' % (uid, study_id), 'success')
|
|
|
|
else:
|
|
|
|
flash('Delete canceled.', 'info')
|
|
|
|
|
2020-05-24 23:05:57 -04:00
|
|
|
return redirect_home()
|
2020-02-17 13:25:14 -05:00
|
|
|
|
|
|
|
|
2020-08-12 19:15:16 -04:00
|
|
|
@app.route('/study_sponsor/<study_id>', methods=['GET', 'POST'])
|
2020-08-13 15:19:55 -04:00
|
|
|
def edit_study_sponsor(study_id):
|
|
|
|
study = db.session.query(Study).filter(Study.STUDYID == study_id).first()
|
2020-08-12 19:15:16 -04:00
|
|
|
form = StudySponsorForm(request.form)
|
|
|
|
action = BASE_HREF + "/study_sponsor/" + study_id
|
2020-08-13 15:19:55 -04:00
|
|
|
title = "Edit sponsors for Study " + study_id
|
|
|
|
form.SPONSOR_IDS.choices = [(s.SPONSOR_ID, f'{s.SP_NAME} ({s.SP_TYPE})') for s in db.session.query(Sponsor).all()]
|
|
|
|
|
|
|
|
if request.method == 'GET':
|
|
|
|
if hasattr(study, 'sponsors'):
|
|
|
|
form.SPONSOR_IDS.data = [s.SPONSOR_ID for s in study.sponsors]
|
|
|
|
|
2020-08-12 19:15:16 -04:00
|
|
|
if request.method == 'POST':
|
2020-08-13 15:19:55 -04:00
|
|
|
# Remove all existing sponsors
|
|
|
|
session.query(StudySponsor).filter(StudySponsor.SS_STUDY == study_id).delete()
|
|
|
|
|
|
|
|
# Add the new ones
|
|
|
|
for sponsor_id in form.SPONSOR_IDS.data:
|
|
|
|
study_sponsor = StudySponsor(SS_STUDY=study_id, SPONSOR_ID=sponsor_id)
|
|
|
|
db.session.add(study_sponsor)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
sponsor_label = 'sponsor' if len(form.SPONSOR_IDS.data) == 1 else 'sponsors'
|
|
|
|
flash(f'Study {sponsor_label} edited successfully!', 'success')
|
2020-08-12 19:15:16 -04:00
|
|
|
return redirect_home()
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
description_map={},
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/del_study_sponsor/<study_sponsor_id>', methods=['GET', 'POST'])
|
|
|
|
def del_study_sponsor(study_sponsor_id):
|
|
|
|
study_sponsor_id = int(study_sponsor_id)
|
2020-08-13 15:19:55 -04:00
|
|
|
study_sponsor_model: StudySponsor = db.session.query(StudySponsor).filter(StudySponsor.id == study_sponsor_id).first()
|
|
|
|
|
2020-08-12 19:15:16 -04:00
|
|
|
if study_sponsor_model is None:
|
|
|
|
flash('StudySponsor not found.', 'warn')
|
|
|
|
return redirect_home()
|
|
|
|
|
2020-08-13 15:19:55 -04:00
|
|
|
sponsor_span = f'<span class="highlight">{study_sponsor_model.sponsor.SP_NAME} ' \
|
|
|
|
f'({study_sponsor_model.sponsor.SP_TYPE})</span>'
|
|
|
|
study_id = int(study_sponsor_model.SS_STUDY)
|
2020-08-12 19:15:16 -04:00
|
|
|
form = ConfirmDeleteForm(request.form, obj=study_sponsor_model)
|
|
|
|
|
|
|
|
if request.method == 'GET':
|
2020-08-13 15:19:55 -04:00
|
|
|
action = f'{BASE_HREF}/del_study_sponsor/{study_sponsor_id}'
|
|
|
|
title = 'Remove study sponsor?'
|
|
|
|
details = f'Are you sure you want to remove {sponsor_span} ' \
|
|
|
|
f'as a sponsor of Study {study_id}? ' \
|
|
|
|
f'This will not remove the sponsor itself from the system.'
|
2020-08-12 19:15:16 -04:00
|
|
|
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
details=details,
|
|
|
|
description_map=description_map,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
if form.confirm and form.confirm.data:
|
|
|
|
db.session.query(StudySponsor).filter(StudySponsor.id == study_sponsor_id).delete()
|
|
|
|
db.session.commit()
|
2020-08-13 15:19:55 -04:00
|
|
|
flash(f'Sponsor {sponsor_span} removed from Study {study_id}.', 'success')
|
2020-08-12 19:15:16 -04:00
|
|
|
else:
|
|
|
|
flash('Delete canceled.', 'info')
|
|
|
|
|
|
|
|
return redirect_home()
|
|
|
|
|
|
|
|
|
2020-06-30 14:48:11 -04:00
|
|
|
@app.route('/del_study/<study_id>', methods=['GET', 'POST'])
|
2020-02-17 13:25:14 -05:00
|
|
|
def del_study(study_id):
|
2020-06-30 14:48:11 -04:00
|
|
|
study_id = int(study_id)
|
|
|
|
study_model = db.session.query(Study).filter(Study.STUDYID == study_id).first()
|
|
|
|
if study_model is None:
|
|
|
|
flash('Study not found.', 'warn')
|
|
|
|
return redirect_home()
|
|
|
|
|
|
|
|
form = ConfirmDeleteForm(request.form, obj=study_model)
|
|
|
|
|
|
|
|
if request.method == 'GET':
|
2020-08-13 15:19:55 -04:00
|
|
|
action = f'{BASE_HREF}/del_study/{study_id}'
|
|
|
|
title = f'Delete Study #{study_id}?'
|
|
|
|
details = f'Are you sure you want to delete Study <span class="highlight">{study_model.TITLE}</span>?'
|
2020-06-30 14:48:11 -04:00
|
|
|
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
details=details,
|
|
|
|
description_map=description_map,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
if form.confirm and form.confirm.data:
|
|
|
|
db.session.query(RequiredDocument).filter(RequiredDocument.STUDYID == study_id).delete()
|
|
|
|
db.session.query(Investigator).filter(Investigator.STUDYID == study_id).delete()
|
|
|
|
db.session.query(StudyDetails).filter(StudyDetails.STUDYID == study_id).delete()
|
2020-08-13 15:19:55 -04:00
|
|
|
db.session.query(StudySponsor).filter(StudySponsor.SS_STUDY == study_id).delete()
|
|
|
|
study = db.session.query(Study).filter(Study.STUDYID == study_id).first()
|
|
|
|
session.delete(study)
|
2020-06-30 14:48:11 -04:00
|
|
|
db.session.commit()
|
|
|
|
flash('Study %i deleted.' % study_id, 'success')
|
|
|
|
else:
|
|
|
|
flash('Delete canceled.', 'info')
|
|
|
|
|
|
|
|
return redirect_home()
|
2020-02-17 11:43:26 -05:00
|
|
|
|
|
|
|
|
|
|
|
def _update_study(study, form):
|
2020-04-17 11:27:12 -04:00
|
|
|
if study.STUDYID is None:
|
|
|
|
# quick hack to get auto-increment without creating a bunch of hassle, this is not
|
|
|
|
# production code by any stretch of the imagination, but this is a throw away library.
|
|
|
|
max_id = db.session.query(func.max(Study.STUDYID)).scalar() or 1
|
|
|
|
|
|
|
|
study.STUDYID = max_id + 1
|
|
|
|
else:
|
|
|
|
db.session.query(RequiredDocument).filter(RequiredDocument.STUDYID == study.STUDYID).delete()
|
2020-02-28 11:16:12 -05:00
|
|
|
|
2020-02-17 16:21:18 -05:00
|
|
|
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
|
2020-02-28 11:16:12 -05:00
|
|
|
|
|
|
|
for r in form.requirements:
|
|
|
|
if r.checked:
|
|
|
|
requirement = RequiredDocument(AUXDOCID=r.data, AUXDOC=r.label.text, study=study)
|
|
|
|
db.session.add(requirement)
|
|
|
|
|
2020-02-17 11:43:26 -05:00
|
|
|
db.session.add(study)
|
|
|
|
db.session.commit()
|
|
|
|
|
2020-04-17 11:27:12 -04:00
|
|
|
|
2020-05-24 00:05:24 -04:00
|
|
|
@app.route('/study_details/<study_id>', methods=['GET', 'POST'])
|
2020-02-17 16:21:18 -05:00
|
|
|
def study_details(study_id):
|
|
|
|
study_details = db.session.query(StudyDetails).filter(StudyDetails.STUDYID == study_id).first()
|
|
|
|
if not study_details:
|
|
|
|
study_details = StudyDetails(STUDYID=study_id)
|
|
|
|
form = StudyDetailsForm(request.form, obj=study_details)
|
|
|
|
if request.method == 'GET':
|
2020-05-24 23:05:57 -04:00
|
|
|
action = BASE_HREF + "/study_details/" + study_id
|
2020-02-17 16:21:18 -05:00
|
|
|
title = "Edit Study Details for Study #" + study_id
|
|
|
|
details = "Numeric fields can be 1 for true, 0 or false, or Null if not applicable."
|
|
|
|
if request.method == 'POST':
|
|
|
|
form.populate_obj(study_details)
|
|
|
|
db.session.add(study_details)
|
|
|
|
db.session.commit()
|
2020-06-30 14:48:11 -04:00
|
|
|
flash('Study updated successfully!', 'success')
|
2020-05-24 23:05:57 -04:00
|
|
|
return redirect_home()
|
|
|
|
return render_template(
|
|
|
|
'form.html',
|
|
|
|
form=form,
|
|
|
|
action=action,
|
|
|
|
title=title,
|
|
|
|
details=details,
|
|
|
|
description_map=description_map,
|
|
|
|
base_href=BASE_HREF
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def redirect_home():
|
2020-05-25 11:41:39 -04:00
|
|
|
return redirect(url_for('index'))
|
2020-02-14 15:19:30 -05:00
|
|
|
|
2020-02-17 13:25:14 -05:00
|
|
|
|
2020-01-08 16:05:16 -05:00
|
|
|
if __name__ == '__main__':
|
|
|
|
# run our standalone gevent server
|
2020-02-26 12:17:37 -05:00
|
|
|
app.run(port=4200)
|