Adds documents_status StudyInfo script. Adds Documents & Approvals workflow spec.
This commit is contained in:
parent
2e601719ad
commit
d91f690388
|
@ -48,7 +48,7 @@ For example:
|
|||
|
||||
def get_documents(self, study_id, pb_docs):
|
||||
"""Takes data from the protocol builder, and merges it with data from the IRB Pro Categories spreadsheet to return
|
||||
pertinant details about the required documents."""
|
||||
pertinent details about the required documents."""
|
||||
|
||||
doc_dictionary = FileService.get_file_reference_dictionary()
|
||||
required_docs = {}
|
||||
|
|
|
@ -3,6 +3,7 @@ from ldap3.core.exceptions import LDAPSocketOpenError
|
|||
from crc import session, app
|
||||
from crc.api.common import ApiError
|
||||
from crc.models.study import StudyModel, StudySchema
|
||||
from crc.models.workflow import WorkflowStatus
|
||||
from crc.scripts.script import Script
|
||||
from crc.services.ldap_service import LdapService
|
||||
from crc.services.protocol_builder import ProtocolBuilderService
|
||||
|
@ -14,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."""
|
||||
pb = ProtocolBuilderService()
|
||||
type_options = ['info', 'investigators', 'details', 'approvals']
|
||||
type_options = ['info', 'investigators', 'details', 'approvals', 'documents_status']
|
||||
|
||||
def get_description(self):
|
||||
return """StudyInfo [TYPE], where TYPE is one of 'info', 'investigators', or 'details'
|
||||
|
@ -47,7 +48,27 @@ class StudyInfo(Script):
|
|||
"NETBADGEID": "dhf8r"
|
||||
},
|
||||
"details":
|
||||
{}
|
||||
{},
|
||||
"approvals": {
|
||||
"id": 321,
|
||||
"display_name": "IRB API Details",
|
||||
"name": "irb_api_details",
|
||||
"status": WorkflowStatus.not_started.value,
|
||||
"workflow_spec_id": "irb_api_details",
|
||||
},
|
||||
"documents_status": [
|
||||
{
|
||||
'category1': 'Ancillary Document',
|
||||
'category2': 'CoC Application',
|
||||
'category3': '',
|
||||
'Who Uploads?': 'CRC',
|
||||
'Id': '12',
|
||||
'Name': 'Certificate of Confidentiality Application',
|
||||
'count': 0,
|
||||
'required': False,
|
||||
'code': 'AD_CoCApp'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
self.add_data_to_task(task=task, data=data["study"])
|
||||
|
@ -71,6 +92,9 @@ class StudyInfo(Script):
|
|||
self.add_data_to_task(task, {cmd: self.pb.get_study_details(study_id)})
|
||||
if cmd == 'approvals':
|
||||
self.add_data_to_task(task, {cmd: StudyService().get_approvals(study_id)})
|
||||
if cmd == 'documents_status':
|
||||
self.add_data_to_task(task, {cmd: StudyService().get_documents_status(study_id)})
|
||||
|
||||
task.data["study"] = study_info
|
||||
|
||||
|
||||
|
|
|
@ -4,11 +4,14 @@ from SpiffWorkflow import WorkflowException
|
|||
|
||||
from crc import db, session
|
||||
from crc.api.common import ApiError
|
||||
from crc.models.file import FileModel
|
||||
from crc.models.protocol_builder import ProtocolBuilderStudy, ProtocolBuilderStatus
|
||||
from crc.models.stats import WorkflowStatsModel, TaskEventModel
|
||||
from crc.models.study import StudyModel, Study, Category, WorkflowMetadata
|
||||
from crc.models.workflow import WorkflowSpecCategoryModel, WorkflowModel, WorkflowSpecModel, WorkflowState, \
|
||||
WorkflowStatus
|
||||
from crc.scripts.documents import Documents
|
||||
from crc.services.file_service import FileService
|
||||
from crc.services.protocol_builder import ProtocolBuilderService
|
||||
from crc.services.workflow_processor import WorkflowProcessor
|
||||
|
||||
|
@ -64,7 +67,7 @@ class StudyService(object):
|
|||
|
||||
@staticmethod
|
||||
def get_approvals(study_id):
|
||||
"""Returns a list of category objects, in the correct order."""
|
||||
"""Returns a list of approval workflows."""
|
||||
cat = session.query(WorkflowSpecCategoryModel).filter_by(name="approvals").first()
|
||||
specs = session.query(WorkflowSpecModel).filter_by(category_id=cat.id).all()
|
||||
spec_ids = [spec.id for spec in specs]
|
||||
|
@ -80,11 +83,44 @@ class StudyService(object):
|
|||
'id': workflow.id,
|
||||
'display_name': workflow.workflow_spec.display_name,
|
||||
'name': workflow.workflow_spec.display_name,
|
||||
'status': workflow.status,
|
||||
'status': workflow.status.value,
|
||||
'workflow_spec_id': workflow.workflow_spec_id,
|
||||
})
|
||||
return approvals
|
||||
|
||||
@staticmethod
|
||||
def get_documents_status(study_id):
|
||||
"""Returns a list of required documents and related workflow status."""
|
||||
doc_service = Documents()
|
||||
|
||||
# Get PB required docs
|
||||
pb_docs = ProtocolBuilderService.get_required_docs(study_id)
|
||||
|
||||
# Get required docs for study
|
||||
study_docs = doc_service.get_documents(study_id=study_id, pb_docs=pb_docs)
|
||||
|
||||
# Container for results
|
||||
documents = []
|
||||
|
||||
# For each required doc, get file(s)
|
||||
for code, doc in study_docs.items():
|
||||
doc['study_id'] = study_id
|
||||
doc['code'] = code
|
||||
doc_files = FileService.get_files(study_id=study_id, irb_doc_code=code)
|
||||
|
||||
# For each file, get associated workflow status
|
||||
for file in doc_files:
|
||||
doc['file_id'] = file.id
|
||||
doc['workflow_id'] = file.workflow_id
|
||||
|
||||
if doc['status'] is None:
|
||||
workflow: WorkflowModel = session.query(WorkflowModel).filter_by(id=file.workflow_id).first()
|
||||
doc['status'] = workflow.status.value
|
||||
|
||||
documents.append(doc)
|
||||
|
||||
return documents
|
||||
|
||||
@staticmethod
|
||||
def synch_all_studies_with_protocol_builder(user):
|
||||
"""Assures that the studies we have locally for the given user are
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_00j2iu5" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<bpmn:process id="Process_1gmf4la" isExecutable="true">
|
||||
<bpmn:documentation />
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1k3su2q</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:endEvent id="EndEvent_1qvyxg7">
|
||||
<bpmn:incoming>Flow_0m7unlb</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0m7unlb" sourceRef="Activity_DisplayDocsAndApprovals" targetRef="EndEvent_1qvyxg7" />
|
||||
<bpmn:manualTask id="Activity_DisplayDocsAndApprovals" name="Display Documents and Approvals">
|
||||
<bpmn:documentation>## Approvals
|
||||
| Name | Status | Help |
|
||||
|:-------------- |:-------- |:------ |
|
||||
{% for approval in StudyInfo.approvals -%}
|
||||
| [{{approval.display_name}}](/workflow/{{approval.id}}) | {{approval.status}} | [Context here](/help/{{approval.workflow_spec_id}}) |
|
||||
{% endfor -%}
|
||||
|
||||
|
||||
## Documents
|
||||
| Code | Status | Help |
|
||||
|:-------------- |:-------- |:------ |
|
||||
{% for doc in study.documents_status -%}
|
||||
| [{{doc.code}}](/study/{{doc.study_id}}/workflow/{{doc.workflow_id}}) | {{doc.status}} | [Context here](/help/{{doc.workflow_spec_id}}) |
|
||||
{% endfor -%}
|
||||
</bpmn:documentation>
|
||||
<bpmn:extensionElements>
|
||||
<camunda:properties>
|
||||
<camunda:property name="display_name" value="Documents and Approvals" />
|
||||
</camunda:properties>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_142jtxs</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0m7unlb</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:scriptTask id="Activity_0a14x7j" name="Load Approvals">
|
||||
<bpmn:incoming>Flow_0c7ryff</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_142jtxs</bpmn:outgoing>
|
||||
<bpmn:script>StudyInfo approvals</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:scriptTask id="Activity_1aju60t" name="Load Documents">
|
||||
<bpmn:incoming>Flow_1k3su2q</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0c7ryff</bpmn:outgoing>
|
||||
<bpmn:script>StudyInfo documents_status</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<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_1k3su2q" sourceRef="StartEvent_1" targetRef="Activity_1aju60t" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1gmf4la">
|
||||
<bpmndi:BPMNEdge id="Flow_0m7unlb_di" bpmnElement="Flow_0m7unlb">
|
||||
<di:waypoint x="710" y="117" />
|
||||
<di:waypoint x="782" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="192" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="EndEvent_1qvyxg7_di" bpmnElement="EndEvent_1qvyxg7">
|
||||
<dc:Bounds x="782" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_19nawos_di" bpmnElement="Activity_DisplayDocsAndApprovals">
|
||||
<dc:Bounds x="610" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1bxk8h3_di" bpmnElement="Activity_0a14x7j">
|
||||
<dc:Bounds x="440" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_07ytvmv_di" bpmnElement="Activity_1aju60t">
|
||||
<dc:Bounds x="290" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_142jtxs_di" bpmnElement="Flow_142jtxs">
|
||||
<di:waypoint x="540" y="117" />
|
||||
<di:waypoint x="610" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0c7ryff_di" bpmnElement="Flow_0c7ryff">
|
||||
<di:waypoint x="390" y="117" />
|
||||
<di:waypoint x="440" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1k3su2q_di" bpmnElement="Flow_1k3su2q">
|
||||
<di:waypoint x="228" y="117" />
|
||||
<di:waypoint x="290" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -79,6 +79,12 @@ class ExampleDataLoader:
|
|||
description="TBD",
|
||||
category_id=0,
|
||||
display_order=1)
|
||||
self.create_spec(id="documents_approvals",
|
||||
name="documents_approvals",
|
||||
display_name="Documents & Approvals",
|
||||
description="TBD",
|
||||
category_id=0,
|
||||
display_order=2)
|
||||
|
||||
# Core Info
|
||||
self.create_spec(id="core_info",
|
||||
|
|
Loading…
Reference in New Issue