Merge branch 'dev' of github.com:sartography/cr-connect-workflow into dev
This commit is contained in:
commit
ca5e984915
|
@ -0,0 +1,47 @@
|
|||
logging_config = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
"loggers": {
|
||||
'': { # root logger
|
||||
'handlers': ['console', 'file'],
|
||||
'level': 'INFO',
|
||||
'propagate': True
|
||||
},
|
||||
'alembic.runtime.migration': {
|
||||
'handlers': ['console', 'file'],
|
||||
'level': 'ERROR',
|
||||
'propagate': False
|
||||
},
|
||||
'urllib3.connectionpool': {
|
||||
'handlers': ['console', 'file'],
|
||||
'level': 'ERROR',
|
||||
'propagate': False
|
||||
},
|
||||
},
|
||||
"formatters": {
|
||||
"simple": {
|
||||
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"level": "DEBUG",
|
||||
"handlers": [
|
||||
"console",
|
||||
"file",
|
||||
]
|
||||
},
|
||||
"handlers": {
|
||||
"console": {
|
||||
"formatter": "simple",
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://sys.stdout",
|
||||
"level": "DEBUG"
|
||||
},
|
||||
"file": {
|
||||
"level": "INFO",
|
||||
"formatter": "simple",
|
||||
"class": "logging.FileHandler",
|
||||
"filename": "cr_connect.log"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import json
|
||||
import logging
|
||||
import logging.config
|
||||
import os
|
||||
|
||||
import click
|
||||
|
@ -19,9 +18,6 @@ from sentry_sdk.integrations.flask import FlaskIntegration
|
|||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
connexion_app = connexion.FlaskApp(__name__)
|
||||
|
||||
app = connexion_app.app
|
||||
|
@ -31,9 +27,13 @@ app.config.from_object('config.default')
|
|||
if "TESTING" in os.environ and os.environ["TESTING"] == "true":
|
||||
app.config.from_object('config.testing')
|
||||
app.config.from_pyfile('../config/testing.py')
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
else:
|
||||
app.config.root_path = app.instance_path
|
||||
app.config.from_pyfile('config.py', silent=True)
|
||||
from config.logging import logging_config
|
||||
logging.config.dictConfig(logging_config)
|
||||
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
|
|
|
@ -41,20 +41,21 @@ class ProtocolBuilderStatus(enum.Enum):
|
|||
class ProtocolBuilderStudy(object):
|
||||
def __init__(
|
||||
self, STUDYID: int, TITLE: str, NETBADGEID: str,
|
||||
DATE_MODIFIED: str
|
||||
DATE_MODIFIED: str, Q_COMPLETE: str, HSRNUMBER: str
|
||||
):
|
||||
self.STUDYID = STUDYID
|
||||
self.TITLE = TITLE
|
||||
self.NETBADGEID = NETBADGEID
|
||||
self.DATE_MODIFIED = DATE_MODIFIED
|
||||
|
||||
self.Q_COMPLETE = Q_COMPLETE
|
||||
self.HSRNUMBER = HSRNUMBER
|
||||
|
||||
class ProtocolBuilderStudySchema(ma.Schema):
|
||||
class Meta:
|
||||
model = ProtocolBuilderStudy
|
||||
unknown = INCLUDE
|
||||
fields = ["STUDYID", "TITLE", "NETBADGEID",
|
||||
"DATE_MODIFIED"]
|
||||
"DATE_MODIFIED", "Q_COMPLETE"]
|
||||
|
||||
@post_load
|
||||
def make_pbs(self, data, **kwargs):
|
||||
|
|
|
@ -195,7 +195,11 @@ Please note this is just a few examples, ALL known document types are returned i
|
|||
if cmd == 'roles':
|
||||
retval = StudyService().get_investigators(study_id, all=True)
|
||||
if cmd == 'details':
|
||||
retval = self.pb.get_study_details(study_id)
|
||||
details = self.pb.get_study_details(study_id)
|
||||
if len(details) > 0:
|
||||
retval = details[0]
|
||||
else:
|
||||
retval = None
|
||||
if cmd == 'sponsors':
|
||||
retval = self.pb.get_sponsors(study_id)
|
||||
if cmd == 'documents':
|
||||
|
|
|
@ -38,8 +38,13 @@ class StudyService(object):
|
|||
|
||||
@staticmethod
|
||||
def _is_valid_study(study_id):
|
||||
study_info = ProtocolBuilderService().get_study_details(study_id)
|
||||
if 'REVIEW_TYPE' in study_info.keys() and study_info['REVIEW_TYPE'] in [2, 3, 23, 24]:
|
||||
study_info = None
|
||||
study_details = ProtocolBuilderService().get_study_details(study_id)
|
||||
if len(study_details) > 0:
|
||||
study_info = study_details[0]
|
||||
# The review types 2, 3, 23, 24 correspond to review type names
|
||||
# `Full Committee`, `Expedited`, `Non-UVA IRB Full Board`, and `Non-UVA IRB Expedited`
|
||||
if isinstance(study_info, dict) and 'REVIEW_TYPE' in study_info.keys() and study_info['REVIEW_TYPE'] in [2, 3, 23, 24]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -273,8 +278,8 @@ class StudyService(object):
|
|||
for code, doc in doc_dictionary.items():
|
||||
|
||||
doc['required'] = False
|
||||
if ProtocolBuilderService.is_enabled() and doc['id']:
|
||||
pb_data = next((item for item in pb_docs if int(item['AUXDOCID']) == int(doc['id'])), None)
|
||||
if ProtocolBuilderService.is_enabled() and doc['id'] != '':
|
||||
pb_data = next((item for item in pb_docs['AUXDOCS'] if int(item['SS_AUXILIARY_DOC_TYPE_ID']) == int(doc['id'])), None)
|
||||
if pb_data:
|
||||
doc['required'] = True
|
||||
|
||||
|
|
|
@ -1,22 +1,26 @@
|
|||
[
|
||||
{
|
||||
"AUXDOC": "Cancer Center's PRC Approval Form",
|
||||
"AUXDOCID": 6
|
||||
{
|
||||
"AUXDOCS": [ {
|
||||
"AUXILIARY_DOC": "Cancer Center's PRC Approval Form",
|
||||
"SS_AUXILIARY_DOC_TYPE_ID": 6
|
||||
},
|
||||
{
|
||||
"AUXDOC": "InfoSec Approval",
|
||||
"AUXDOCID": "24"
|
||||
"AUXILIARY_DOC": "InfoSec Approval",
|
||||
"SS_AUXILIARY_DOC_TYPE_ID": "24"
|
||||
},
|
||||
{
|
||||
"AUXDOC": "Scientific Pre-review Documentation",
|
||||
"AUXDOCID": "25"
|
||||
"AUXILIARY_DOC": "Scientific Pre-review Documentation",
|
||||
"SS_AUXILIARY_DOC_TYPE_ID": "25"
|
||||
},
|
||||
{
|
||||
"AUXDOC": "GMEC Approval",
|
||||
"AUXDOCID": "45"
|
||||
"AUXILIARY_DOC": "GMEC Approval",
|
||||
"SS_AUXILIARY_DOC_TYPE_ID": "45"
|
||||
},
|
||||
{
|
||||
"AUXDOC": "Laser Safety Officer Approval",
|
||||
"AUXDOCID": "57"
|
||||
"AUXILIARY_DOC": "Laser Safety Officer Approval",
|
||||
"SS_AUXILIARY_DOC_TYPE_ID": "57"
|
||||
}
|
||||
]
|
||||
],
|
||||
"OTHERDOCS": [],
|
||||
"TEMPLATEDOCS": []
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
[{
|
||||
"DSMB": 1,
|
||||
"DSMB_FREQUENCY": 2,
|
||||
"GCRC_NUMBER": "9",
|
||||
|
@ -64,4 +64,4 @@
|
|||
"SPONSORS_PROTOCOL_REVISION_DATE": "2021-04-20",
|
||||
"UPLOAD_COMPLETE": null,
|
||||
"REVIEW_TYPE": 2
|
||||
}
|
||||
}]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
[{
|
||||
"DSMB": 1,
|
||||
"DSMB_FREQUENCY": 2,
|
||||
"GCRC_NUMBER": "9",
|
||||
|
@ -64,4 +64,4 @@
|
|||
"SPONSORS_PROTOCOL_REVISION_DATE": "2021-04-20",
|
||||
"UPLOAD_COMPLETE": null,
|
||||
"REVIEW_TYPE": 99
|
||||
}
|
||||
}]
|
||||
|
|
|
@ -3,18 +3,24 @@
|
|||
"DATE_MODIFIED": "2020-02-19T14:26:49.127756",
|
||||
"NETBADGEID": "dhf8r",
|
||||
"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",
|
||||
"Q_COMPLETE": 0,
|
||||
"HSRNUMBER": null
|
||||
},
|
||||
{
|
||||
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
||||
"NETBADGEID": "dhf8r",
|
||||
"STUDYID": 65432,
|
||||
"TITLE": "Peanut butter consumption among quiet dogs"
|
||||
"TITLE": "Peanut butter consumption among quiet dogs",
|
||||
"Q_COMPLETE": 0,
|
||||
"HSRNUMBER": null
|
||||
},
|
||||
{
|
||||
"DATE_MODIFIED": "2020-02-19T14:24:55.101695",
|
||||
"NETBADGEID": "dhf8r",
|
||||
"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",
|
||||
"Q_COMPLETE": 0,
|
||||
"HSRNUMBER": null
|
||||
}
|
||||
]
|
||||
|
|
|
@ -35,16 +35,17 @@ class TestProtocolBuilder(BaseTest):
|
|||
mock_get.return_value.ok = True
|
||||
mock_get.return_value.text = self.protocol_builder_response('required_docs.json')
|
||||
response = ProtocolBuilderService.get_required_docs(self.test_study_id)
|
||||
self.assertIsNotNone(response)
|
||||
self.assertEqual(5, len(response))
|
||||
self.assertEqual(6, response[0]['AUXDOCID'])
|
||||
auxdocs = response['AUXDOCS']
|
||||
self.assertIsNotNone(auxdocs)
|
||||
self.assertEqual(5, len(auxdocs))
|
||||
self.assertEqual(6, auxdocs[0]['SS_AUXILIARY_DOC_TYPE_ID'])
|
||||
|
||||
@patch('crc.services.protocol_builder.requests.get')
|
||||
def test_get_details(self, mock_get):
|
||||
app.config['PB_ENABLED'] = True
|
||||
mock_get.return_value.ok = True
|
||||
mock_get.return_value.text = self.protocol_builder_response('study_details.json')
|
||||
response = ProtocolBuilderService.get_study_details(self.test_study_id)
|
||||
response = ProtocolBuilderService.get_study_details(self.test_study_id)[0]
|
||||
self.assertIsNotNone(response)
|
||||
self.assertEqual(65, len(response))
|
||||
self.assertEqual('1234', response['IND_1'])
|
||||
|
|
|
@ -76,7 +76,7 @@ class TestStudyInfoScript(BaseTest):
|
|||
app.config['PB_ENABLED'] = True
|
||||
mock_get.return_value.ok = True
|
||||
mock_get.return_value.text = self.protocol_builder_response('study_details.json')
|
||||
response = ProtocolBuilderService.get_study_details(self.test_study_id)
|
||||
response = ProtocolBuilderService.get_study_details(self.test_study_id)[0]
|
||||
study_info, second_task = self.do_work(info_type='details')
|
||||
self.assertEqual(response['IBC_NUMBER'], second_task.data['info']['IBC_NUMBER'])
|
||||
self.assertEqual(response['IDE'], second_task.data['info']['IDE'])
|
||||
|
@ -84,7 +84,12 @@ class TestStudyInfoScript(BaseTest):
|
|||
self.assertEqual(response['IND_2'], second_task.data['info']['IND_2'])
|
||||
self.assertEqual(response['IND_3'], second_task.data['info']['IND_3'])
|
||||
|
||||
def test_info_script_documents(self):
|
||||
@patch('crc.services.protocol_builder.requests.get')
|
||||
def test_info_script_documents(self, mock_get):
|
||||
app.config['PB_ENABLED'] = True
|
||||
mock_get.return_value.ok = True
|
||||
mock_get.return_value.text = self.protocol_builder_response('required_docs.json')
|
||||
response = ProtocolBuilderService.get_required_docs(self.test_study_id)
|
||||
study_info, second_task = self.do_work(info_type='documents')
|
||||
self.assertEqual(study_info, second_task.data['info'])
|
||||
self.assertEqual(0, len(study_info['Grant_App']['files']), "Grant_App has not files yet.")
|
||||
|
|
Loading…
Reference in New Issue