Adds protocol script to study service

This commit is contained in:
Aaron Louie 2020-04-29 10:21:24 -04:00
parent 13333fb306
commit beb86f0453
5 changed files with 72 additions and 23 deletions

View File

@ -15,7 +15,7 @@ class StudyInfo(Script):
"""Just your basic class that can pull in data from a few api endpoints and do a basic task.""" """Just your basic class that can pull in data from a few api endpoints and do a basic task."""
pb = ProtocolBuilderService() pb = ProtocolBuilderService()
type_options = ['info', 'investigators', 'details', 'approvals', 'documents_status'] type_options = ['info', 'investigators', 'details', 'approvals', 'documents_status', 'protocol']
def get_description(self): def get_description(self):
return """StudyInfo [TYPE], where TYPE is one of 'info', 'investigators', or 'details' return """StudyInfo [TYPE], where TYPE is one of 'info', 'investigators', or 'details'
@ -75,7 +75,10 @@ class StudyInfo(Script):
'workflow_spec_id': 'irb_api_details', 'workflow_spec_id': 'irb_api_details',
'status': 'complete', 'status': 'complete',
} }
] ],
'protocol': {
id: 0,
}
} }
} }
self.add_data_to_task(task=task, data=data["study"]) self.add_data_to_task(task=task, data=data["study"])
@ -101,6 +104,8 @@ class StudyInfo(Script):
self.add_data_to_task(task, {cmd: StudyService().get_approvals(study_id)}) self.add_data_to_task(task, {cmd: StudyService().get_approvals(study_id)})
if cmd == 'documents_status': if cmd == 'documents_status':
self.add_data_to_task(task, {cmd: StudyService().get_documents_status(study_id)}) self.add_data_to_task(task, {cmd: StudyService().get_documents_status(study_id)})
if cmd == 'protocol':
self.add_data_to_task(task, {cmd: StudyService().get_protocol(study_id)})
def check_args(self, args): def check_args(self, args):

View File

@ -168,7 +168,7 @@ class FileService(object):
if form_field_key: if form_field_key:
query = query.filter_by(form_field_key=form_field_key) query = query.filter_by(form_field_key=form_field_key)
if name: if name:
query = query.filter_by(name=form_field_key) query = query.filter_by(name=name)
if irb_doc_code: if irb_doc_code:
query = query.filter_by(irb_doc_code=irb_doc_code) query = query.filter_by(irb_doc_code=irb_doc_code)

View File

@ -1,10 +1,11 @@
import json
from typing import List from typing import List
from SpiffWorkflow import WorkflowException from SpiffWorkflow import WorkflowException
from crc import db, session from crc import db, session
from crc.api.common import ApiError from crc.api.common import ApiError
from crc.models.file import FileModel from crc.models.file import FileModel, FileModelSchema
from crc.models.protocol_builder import ProtocolBuilderStudy, ProtocolBuilderStatus from crc.models.protocol_builder import ProtocolBuilderStudy, ProtocolBuilderStatus
from crc.models.stats import WorkflowStatsModel, TaskEventModel from crc.models.stats import WorkflowStatsModel, TaskEventModel
from crc.models.study import StudyModel, Study, Category, WorkflowMetadata from crc.models.study import StudyModel, Study, Category, WorkflowMetadata
@ -105,6 +106,9 @@ class StudyService(object):
# Container for results # Container for results
documents = [] documents = []
# Study > Categories > Workflows
study = StudyService.get_study(study_id)
# For each required doc, get file(s) # For each required doc, get file(s)
for code, doc in study_docs.items(): for code, doc in study_docs.items():
if not doc['required']: if not doc['required']:
@ -123,6 +127,15 @@ class StudyService(object):
name_list.append(doc[cat_key]) name_list.append(doc[cat_key])
doc['display_name'] = ' '.join(name_list) doc['display_name'] = ' '.join(name_list)
# print('code', code)
#
# # Find which workflows have the associated irb_doc_code???
# wf = db.session.query(WorkflowModel)\
# .filter_by(study_id=study_id)\
# .filter(WorkflowModel.bpmn_workflow_json.contains(code))\
# .first()
# print('wf', wf)
# For each file, get associated workflow status # For each file, get associated workflow status
doc_files = FileService.get_files(study_id=study_id, irb_doc_code=code) doc_files = FileService.get_files(study_id=study_id, irb_doc_code=code)
for file in doc_files: for file in doc_files:
@ -139,6 +152,18 @@ class StudyService(object):
return documents return documents
@staticmethod
def get_protocol(study_id):
"""Returns the study protocol, if it has been uploaded."""
file = db.session.query(FileModel)\
.filter_by(study_id=study_id)\
.filter_by(form_field_key='Study_Protocol_Document')\
.first()
return FileModelSchema().dump(file)
@staticmethod @staticmethod
def synch_all_studies_with_protocol_builder(user): def synch_all_studies_with_protocol_builder(user):
"""Assures that the studies we have locally for the given user are """Assures that the studies we have locally for the given user are

View File

@ -13,13 +13,19 @@
<bpmn:documentation># Documents &amp; Approvals <bpmn:documentation># Documents &amp; Approvals
&gt; ## Protocol Document Management &gt; ## Protocol Document Management
&gt; [Upload Protocol Here](/) {% if StudyInfo.protocol is defined -%}
{%- set p = StudyInfo.protocol -%}
&gt; [{{p.name}}](/study/{{p.study_id}}/workflow/{{p.workflow_id}}/task/{{p.task_id}})
{%- else -%}
&gt; No protocol uploaded yet.
{% endif %}
&gt; ## Approvals &gt; ## Approvals
&gt; | Name | Status | Help | &gt; | Name | Status | Help |
|:---- |:------ |:---- | |:---- |:------ |:---- |
{% for approval in StudyInfo.approvals -%} {% for approval in StudyInfo.approvals -%}
| [{{approval.display_name}}](/study/{{approval.study_id}}/workflow/{{approval.workflow_id}}) | {{approval.status}} | [Context here](/help/{{approval.workflow_spec_id}}) | | [{{approval.display_name}}](/study/{{approval.study_id}}/workflow/{{approval.workflow_id}}) | {{approval.status}} | [?](/help/{{approval.workflow_spec_id}}) |
{% endfor %} {% endfor %}
&gt; ## Documents &gt; ## Documents
@ -27,9 +33,9 @@
|:---- |:------ |:---- |:-------- | |:---- |:------ |:---- |:-------- |
{% for doc in StudyInfo.documents_status -%} {% for doc in StudyInfo.documents_status -%}
{% if doc.file_id is defined -%} {% if doc.file_id is defined -%}
| [{{doc.display_name}}](/study/{{doc.study_id}}/workflow/{{doc.workflow_id}}/task/{{doc.task_id}}) | {{doc.status}} | [Context here](/help/documents/{{doc.code}}) | [Download](/file/{{doc.file_id}}) | | [{{doc.display_name}}](/study/{{doc.study_id}}/workflow/{{doc.workflow_id}}/task/{{doc.task_id}}) | {{doc.status}} | [Context here](/help/documents/{{doc.code}}) | [Download](/file/{{doc.file_id}}/data) |
{%- else -%} {%- else -%}
| {{doc.display_name}} | Not started | [Context here](/help/documents/{{doc.code}}) | No file yet | | {{doc.display_name}} | Not started | [?](/help/documents/{{doc.code}}) | No file yet |
{%- endif %} {%- endif %}
{% endfor %}</bpmn:documentation> {% endfor %}</bpmn:documentation>
<bpmn:extensionElements> <bpmn:extensionElements>
@ -46,47 +52,60 @@
<bpmn:script>StudyInfo approvals</bpmn:script> <bpmn:script>StudyInfo approvals</bpmn:script>
</bpmn:scriptTask> </bpmn:scriptTask>
<bpmn:scriptTask id="Activity_1aju60t" name="Load Documents"> <bpmn:scriptTask id="Activity_1aju60t" name="Load Documents">
<bpmn:incoming>Flow_1k3su2q</bpmn:incoming> <bpmn:incoming>Flow_0w20w9j</bpmn:incoming>
<bpmn:outgoing>Flow_0c7ryff</bpmn:outgoing> <bpmn:outgoing>Flow_0c7ryff</bpmn:outgoing>
<bpmn:script>StudyInfo documents_status</bpmn:script> <bpmn:script>StudyInfo documents_status</bpmn:script>
</bpmn:scriptTask> </bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_142jtxs" sourceRef="Activity_0a14x7j" targetRef="Activity_DisplayDocsAndApprovals" /> <bpmn:sequenceFlow id="Flow_142jtxs" sourceRef="Activity_0a14x7j" targetRef="Activity_DisplayDocsAndApprovals" />
<bpmn:sequenceFlow id="Flow_0c7ryff" sourceRef="Activity_1aju60t" targetRef="Activity_0a14x7j" /> <bpmn:sequenceFlow id="Flow_0c7ryff" sourceRef="Activity_1aju60t" targetRef="Activity_0a14x7j" />
<bpmn:sequenceFlow id="Flow_1k3su2q" sourceRef="StartEvent_1" targetRef="Activity_1aju60t" /> <bpmn:sequenceFlow id="Flow_1k3su2q" sourceRef="StartEvent_1" targetRef="Activity_0b4ojeq" />
<bpmn:scriptTask id="Activity_0b4ojeq" name="Load Protocol">
<bpmn:incoming>Flow_1k3su2q</bpmn:incoming>
<bpmn:outgoing>Flow_0w20w9j</bpmn:outgoing>
<bpmn:script>StudyInfo protocol</bpmn:script>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_0w20w9j" sourceRef="Activity_0b4ojeq" targetRef="Activity_1aju60t" />
</bpmn:process> </bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1gmf4la"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1gmf4la">
<bpmndi:BPMNEdge id="Flow_1k3su2q_di" bpmnElement="Flow_1k3su2q"> <bpmndi:BPMNEdge id="Flow_1k3su2q_di" bpmnElement="Flow_1k3su2q">
<di:waypoint x="228" y="117" /> <di:waypoint x="188" y="117" />
<di:waypoint x="290" y="117" /> <di:waypoint x="240" y="117" />
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0c7ryff_di" bpmnElement="Flow_0c7ryff"> <bpmndi:BPMNEdge id="Flow_0c7ryff_di" bpmnElement="Flow_0c7ryff">
<di:waypoint x="390" y="117" /> <di:waypoint x="490" y="117" />
<di:waypoint x="440" y="117" /> <di:waypoint x="540" y="117" />
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_142jtxs_di" bpmnElement="Flow_142jtxs"> <bpmndi:BPMNEdge id="Flow_142jtxs_di" bpmnElement="Flow_142jtxs">
<di:waypoint x="540" y="117" /> <di:waypoint x="640" y="117" />
<di:waypoint x="610" y="117" /> <di:waypoint x="710" y="117" />
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0m7unlb_di" bpmnElement="Flow_0m7unlb"> <bpmndi:BPMNEdge id="Flow_0m7unlb_di" bpmnElement="Flow_0m7unlb">
<di:waypoint x="710" y="117" /> <di:waypoint x="810" y="117" />
<di:waypoint x="782" y="117" /> <di:waypoint x="882" y="117" />
</bpmndi:BPMNEdge> </bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1"> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="192" y="99" width="36" height="36" /> <dc:Bounds x="152" y="99" width="36" height="36" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="EndEvent_1qvyxg7_di" bpmnElement="EndEvent_1qvyxg7"> <bpmndi:BPMNShape id="EndEvent_1qvyxg7_di" bpmnElement="EndEvent_1qvyxg7">
<dc:Bounds x="782" y="99" width="36" height="36" /> <dc:Bounds x="882" y="99" width="36" height="36" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_19nawos_di" bpmnElement="Activity_DisplayDocsAndApprovals"> <bpmndi:BPMNShape id="Activity_19nawos_di" bpmnElement="Activity_DisplayDocsAndApprovals">
<dc:Bounds x="610" y="77" width="100" height="80" /> <dc:Bounds x="710" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1bxk8h3_di" bpmnElement="Activity_0a14x7j"> <bpmndi:BPMNShape id="Activity_1bxk8h3_di" bpmnElement="Activity_0a14x7j">
<dc:Bounds x="440" y="77" width="100" height="80" /> <dc:Bounds x="540" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_07ytvmv_di" bpmnElement="Activity_1aju60t"> <bpmndi:BPMNShape id="Activity_07ytvmv_di" bpmnElement="Activity_1aju60t">
<dc:Bounds x="290" y="77" width="100" height="80" /> <dc:Bounds x="390" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0wf6u3m_di" bpmnElement="Activity_0b4ojeq">
<dc:Bounds x="240" y="77" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0w20w9j_di" bpmnElement="Flow_0w20w9j">
<di:waypoint x="340" y="117" />
<di:waypoint x="390" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane> </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram> </bpmndi:BPMNDiagram>
</bpmn:definitions> </bpmn:definitions>