mirror of
https://github.com/sartography/cr-connect-workflow.git
synced 2025-02-21 20:28:10 +00:00
Adds status spec when adding a study, and adds/removes workflows from study based on output data from status spec.
This commit is contained in:
parent
e4af6f77d0
commit
bdd07685c6
@ -23,16 +23,46 @@ def all_studies():
|
||||
|
||||
@auth.login_required
|
||||
def add_study(body):
|
||||
study = StudyModelSchema().load(body, session=session)
|
||||
study: StudyModel = StudyModelSchema().load(body, session=session)
|
||||
status_spec = __get_status_spec(study.status_spec_id)
|
||||
|
||||
# Get latest status spec version
|
||||
if status_spec is not None:
|
||||
study.status_spec_id = status_spec.id
|
||||
study.status_spec_version = WorkflowProcessor.get_latest_version_string(status_spec.id)
|
||||
|
||||
session.add(study)
|
||||
session.commit()
|
||||
|
||||
# FIXME: We need to ask the protocol builder what workflows to add to the study, not just add them all.
|
||||
for spec in session.query(WorkflowSpecModel).all():
|
||||
WorkflowProcessor.create(study.id, spec.id)
|
||||
__add_study_workflows_from_status(study.id, status_spec)
|
||||
return StudyModelSchema().dump(study)
|
||||
|
||||
|
||||
def __get_status_spec(status_spec_id):
|
||||
if status_spec_id is None:
|
||||
return session.query(WorkflowSpecModel).filter_by(is_status=True).first()
|
||||
else:
|
||||
return session.query(WorkflowSpecModel).filter_by(id=status_spec_id).first()
|
||||
|
||||
|
||||
def __add_study_workflows_from_status(study_id, status_spec):
|
||||
all_specs = session.query(WorkflowSpecModel).all()
|
||||
if status_spec is not None:
|
||||
# Run status spec to get list of workflow specs applicable to this study
|
||||
status_processor = WorkflowProcessor.create(study_id, status_spec)
|
||||
status_processor.do_engine_steps()
|
||||
status_data = status_processor.next_task().data
|
||||
|
||||
# Only add workflow specs listed in status spec
|
||||
for spec in all_specs:
|
||||
if spec.id in status_data and status_data[spec.id]:
|
||||
WorkflowProcessor.create(study_id, spec.id)
|
||||
else:
|
||||
# No status spec. Just add all workflows.
|
||||
for spec in all_specs:
|
||||
WorkflowProcessor.create(study_id, spec.id)
|
||||
|
||||
|
||||
@auth.login_required
|
||||
def update_study(study_id, body):
|
||||
if study_id is None:
|
||||
@ -130,12 +160,43 @@ def post_update_study_from_protocol_builder(study_id):
|
||||
|
||||
@auth.login_required
|
||||
def get_study_workflows(study_id):
|
||||
workflow_models = session.query(WorkflowModel).filter_by(study_id=study_id).all()
|
||||
|
||||
# Get study
|
||||
study: StudyModel = session.query(StudyModel).filter_by(id=study_id).first()
|
||||
|
||||
# Get study status spec
|
||||
status_spec: WorkflowSpecModel = session.query(WorkflowSpecModel)\
|
||||
.filter_by(is_status=True).first()
|
||||
|
||||
status_data = None
|
||||
|
||||
if status_spec is not None:
|
||||
# Run status spec
|
||||
status_workflow_model: WorkflowModel = session.query(WorkflowModel)\
|
||||
.filter_by(study_id=study.id)\
|
||||
.filter_by(workflow_spec_id=status_spec.id)\
|
||||
.first()
|
||||
status_processor = WorkflowProcessor(status_workflow_model)
|
||||
|
||||
# Get list of active workflow specs for study
|
||||
status_processor.do_engine_steps()
|
||||
status_data = status_processor.bpmn_workflow.last_task.data
|
||||
|
||||
# Get study workflows
|
||||
workflow_models = session.query(WorkflowModel)\
|
||||
.filter_by(study_id=study_id)\
|
||||
.filter(WorkflowModel.workflow_spec_id != status_spec.id)\
|
||||
.all()
|
||||
else:
|
||||
# Get study workflows
|
||||
workflow_models = session.query(WorkflowModel)\
|
||||
.filter_by(study_id=study_id)\
|
||||
.all()
|
||||
api_models = []
|
||||
for workflow_model in workflow_models:
|
||||
processor = WorkflowProcessor(workflow_model,
|
||||
workflow_model.bpmn_workflow_json)
|
||||
api_models.append(__get_workflow_api_model(processor))
|
||||
api_models.append(__get_workflow_api_model(processor, status_data))
|
||||
schema = WorkflowApiSchema(many=True)
|
||||
return schema.dump(api_models)
|
||||
|
||||
@ -193,3 +254,4 @@ def map_pb_study_to_study(pb_study):
|
||||
study_info['inactive'] = False
|
||||
return study_info
|
||||
|
||||
|
||||
|
@ -17,7 +17,8 @@ def all_specifications():
|
||||
|
||||
@auth.login_required
|
||||
def add_workflow_specification(body):
|
||||
new_spec = WorkflowSpecModelSchema().load(body, session=session)
|
||||
new_spec: WorkflowSpecModel = WorkflowSpecModelSchema().load(body, session=session)
|
||||
new_spec.is_status = new_spec.id == 'status'
|
||||
session.add(new_spec)
|
||||
session.commit()
|
||||
return WorkflowSpecModelSchema().dump(new_spec)
|
||||
@ -69,9 +70,14 @@ def delete_workflow_specification(spec_id):
|
||||
session.commit()
|
||||
|
||||
|
||||
def __get_workflow_api_model(processor: WorkflowProcessor):
|
||||
def __get_workflow_api_model(processor: WorkflowProcessor, status_data=None):
|
||||
spiff_tasks = processor.get_all_user_tasks()
|
||||
user_tasks = list(map(Task.from_spiff, spiff_tasks))
|
||||
is_active = True
|
||||
|
||||
if status_data is not None and processor.workflow_spec_id in status_data:
|
||||
is_active = status_data[processor.workflow_spec_id]
|
||||
|
||||
workflow_api = WorkflowApi(
|
||||
id=processor.get_workflow_id(),
|
||||
status=processor.get_status(),
|
||||
@ -80,7 +86,8 @@ def __get_workflow_api_model(processor: WorkflowProcessor):
|
||||
user_tasks=user_tasks,
|
||||
workflow_spec_id=processor.workflow_spec_id,
|
||||
spec_version=processor.get_spec_version(),
|
||||
is_latest_spec=processor.get_spec_version() == processor.get_latest_version_string(processor.workflow_spec_id)
|
||||
is_latest_spec=processor.get_spec_version() == processor.get_latest_version_string(processor.workflow_spec_id),
|
||||
is_active=is_active
|
||||
)
|
||||
if processor.next_task():
|
||||
workflow_api.next_task = Task.from_spiff(processor.next_task())
|
||||
@ -89,9 +96,8 @@ def __get_workflow_api_model(processor: WorkflowProcessor):
|
||||
|
||||
@auth.login_required
|
||||
def get_workflow(workflow_id, soft_reset=False, hard_reset=False):
|
||||
workflow_model = session.query(WorkflowModel).filter_by(id=workflow_id).first()
|
||||
workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(id=workflow_id).first()
|
||||
processor = WorkflowProcessor(workflow_model, soft_reset=soft_reset, hard_reset=hard_reset)
|
||||
|
||||
workflow_api_model = __get_workflow_api_model(processor)
|
||||
update_workflow_stats(workflow_model, workflow_api_model)
|
||||
return WorkflowApiSchema().dump(workflow_api_model)
|
||||
|
@ -82,11 +82,11 @@ class ExampleDataLoader:
|
||||
returns an array of data models to be added to the database."""
|
||||
global file
|
||||
file_service = FileService()
|
||||
|
||||
spec = WorkflowSpecModel(id=id,
|
||||
name=name,
|
||||
display_name=display_name,
|
||||
description=description)
|
||||
description=description,
|
||||
is_status=id == 'status')
|
||||
db.session.add(spec)
|
||||
db.session.commit()
|
||||
if not filepath:
|
||||
@ -96,7 +96,7 @@ class ExampleDataLoader:
|
||||
noise, file_extension = os.path.splitext(file_path)
|
||||
filename = os.path.basename(file_path)
|
||||
|
||||
is_status = filename.lower() == 'status'
|
||||
is_status = filename.lower() == 'status.bpmn'
|
||||
is_primary = filename.lower() == id + '.bpmn'
|
||||
try:
|
||||
file = open(file_path, 'rb')
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1p34ouw" name="DRD" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<decision id="should_enable_pb_responses" name="should_enable_pb_responses">
|
||||
<decision id="should_enable_crc2_training_session_data_security_plan" name="should_enable_crc2_training_session_data_security_plan">
|
||||
<extensionElements>
|
||||
<biodi:bounds x="190" y="80" width="180" height="80" />
|
||||
</extensionElements>
|
||||
@ -8,11 +8,19 @@
|
||||
<input id="InputClause_18pwfqu" label="some_input">
|
||||
<inputExpression id="LiteralExpression_1y84stb" typeRef="boolean" expressionLanguage="feel" />
|
||||
</input>
|
||||
<output id="OutputClause_05y0j7c" label="pb_responses" name="pb_responses" typeRef="boolean" />
|
||||
<input id="InputClause_0ahp5b9">
|
||||
<inputExpression id="LiteralExpression_1ptkp9l" typeRef="string">
|
||||
<text></text>
|
||||
</inputExpression>
|
||||
</input>
|
||||
<output id="OutputClause_05y0j7c" label="crc2_training_session_data_security_plan" name="crc2_training_session_data_security_plan" typeRef="boolean" />
|
||||
<rule id="DecisionRule_17xsr74">
|
||||
<inputEntry id="UnaryTests_05ldcq4">
|
||||
<text>false</text>
|
||||
</inputEntry>
|
||||
<inputEntry id="UnaryTests_1ebers6">
|
||||
<text></text>
|
||||
</inputEntry>
|
||||
<outputEntry id="LiteralExpression_09oao3s">
|
||||
<text>false</text>
|
||||
</outputEntry>
|
||||
@ -21,6 +29,9 @@
|
||||
<inputEntry id="UnaryTests_09xdkib">
|
||||
<text>true</text>
|
||||
</inputEntry>
|
||||
<inputEntry id="UnaryTests_1hqb6bs">
|
||||
<text></text>
|
||||
</inputEntry>
|
||||
<outputEntry id="LiteralExpression_0y2v9zc">
|
||||
<text>true</text>
|
||||
</outputEntry>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1p34ouw" name="DRD" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<decision id="should_enable_random_fact" name="should_enable_random_fact">
|
||||
<decision id="should_enable_crc2_training_session_enter_core_info" name="should_enable_crc2_training_session_enter_core_info">
|
||||
<extensionElements>
|
||||
<biodi:bounds x="170" y="60" width="180" height="80" />
|
||||
</extensionElements>
|
||||
@ -10,7 +10,7 @@
|
||||
<text></text>
|
||||
</inputExpression>
|
||||
</input>
|
||||
<output id="output_1" label="random_fact" name="random_fact" typeRef="boolean" />
|
||||
<output id="output_1" label="crc2_training_session_enter_core_info" name="crc2_training_session_enter_core_info" typeRef="boolean" />
|
||||
<rule id="DecisionRule_10oo3ms">
|
||||
<inputEntry id="UnaryTests_1ozg74s">
|
||||
<text>false</text>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1p34ouw" name="DRD" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<decision id="should_enable_study_details" name="should_enable_study_details">
|
||||
<decision id="should_enable_crc2_training_session_sponsor_funding_source" name="should_enable_crc2_training_session_sponsor_funding_source">
|
||||
<extensionElements>
|
||||
<biodi:bounds x="190" y="70" width="180" height="80" />
|
||||
</extensionElements>
|
||||
@ -8,7 +8,7 @@
|
||||
<input id="InputClause_02n3ccs" label="some_input">
|
||||
<inputExpression id="LiteralExpression_1ju4o1o" typeRef="boolean" expressionLanguage="feel" />
|
||||
</input>
|
||||
<output id="OutputClause_1ybi1ud" label="study_details" name="study_details" typeRef="boolean" />
|
||||
<output id="OutputClause_1ybi1ud" label="crc2_training_session_sponsor_funding_source" name="crc2_training_session_sponsor_funding_source" typeRef="boolean" />
|
||||
<rule id="DecisionRule_1t97mw4">
|
||||
<inputEntry id="UnaryTests_0ym4ln2">
|
||||
<text>false</text>
|
@ -5,41 +5,33 @@
|
||||
<bpmn:outgoing>SequenceFlow_1ees8ka</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1ees8ka" sourceRef="StartEvent_1" targetRef="Activity_00rh8pw" />
|
||||
<bpmn:businessRuleTask id="Activity_1k5eeun" name="Enable pb_responses" camunda:decisionRef="should_enable_pb_responses">
|
||||
<bpmn:businessRuleTask id="Activity_1k5eeun" name="Enable crc2_training_session_data_security_plan" camunda:decisionRef="should_enable_crc2_training_session_data_security_plan">
|
||||
<bpmn:incoming>Flow_1nimppb</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1txrak2</bpmn:outgoing>
|
||||
</bpmn:businessRuleTask>
|
||||
<bpmn:businessRuleTask id="Activity_1yqy50i" name="Enable random_fact" camunda:decisionRef="should_enable_random_fact">
|
||||
<bpmn:businessRuleTask id="Activity_1yqy50i" name="Enable crc2_training_session_enter_core_info" camunda:decisionRef="should_enable_crc2_training_session_enter_core_info">
|
||||
<bpmn:incoming>Flow_1m8285h</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1sggkit</bpmn:outgoing>
|
||||
</bpmn:businessRuleTask>
|
||||
<bpmn:businessRuleTask id="Activity_16cm213" name="Enable study_details" camunda:decisionRef="should_enable_study_details">
|
||||
<bpmn:businessRuleTask id="Activity_16cm213" name="Enable crc2_training_session_sponsor_funding_source" camunda:decisionRef="should_enable_crc2_training_session_sponsor_funding_source">
|
||||
<bpmn:incoming>Flow_18pl92p</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0x9580l</bpmn:outgoing>
|
||||
</bpmn:businessRuleTask>
|
||||
<bpmn:businessRuleTask id="Activity_0rbzgsm" name="Enable two_forms" camunda:decisionRef="should_enable_two_forms">
|
||||
<bpmn:incoming>Flow_03u23vt</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0pkxa8l</bpmn:outgoing>
|
||||
</bpmn:businessRuleTask>
|
||||
<bpmn:parallelGateway id="Gateway_1nta7st">
|
||||
<bpmn:incoming>Flow_024q2cw</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1m8285h</bpmn:outgoing>
|
||||
<bpmn:outgoing>Flow_1nimppb</bpmn:outgoing>
|
||||
<bpmn:outgoing>Flow_03u23vt</bpmn:outgoing>
|
||||
<bpmn:outgoing>Flow_18pl92p</bpmn:outgoing>
|
||||
</bpmn:parallelGateway>
|
||||
<bpmn:sequenceFlow id="Flow_1m8285h" sourceRef="Gateway_1nta7st" targetRef="Activity_1yqy50i" />
|
||||
<bpmn:sequenceFlow id="Flow_1nimppb" sourceRef="Gateway_1nta7st" targetRef="Activity_1k5eeun" />
|
||||
<bpmn:sequenceFlow id="Flow_18pl92p" sourceRef="Gateway_1nta7st" targetRef="Activity_16cm213" />
|
||||
<bpmn:sequenceFlow id="Flow_03u23vt" sourceRef="Gateway_1nta7st" targetRef="Activity_0rbzgsm" />
|
||||
<bpmn:parallelGateway id="Gateway_12tpgcy">
|
||||
<bpmn:incoming>Flow_1txrak2</bpmn:incoming>
|
||||
<bpmn:incoming>Flow_0pkxa8l</bpmn:incoming>
|
||||
<bpmn:incoming>Flow_1sggkit</bpmn:incoming>
|
||||
<bpmn:incoming>Flow_0x9580l</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0pwtiqm</bpmn:outgoing>
|
||||
</bpmn:parallelGateway>
|
||||
<bpmn:sequenceFlow id="Flow_0pkxa8l" sourceRef="Activity_0rbzgsm" targetRef="Gateway_12tpgcy" />
|
||||
<bpmn:endEvent id="Event_135x8jg">
|
||||
<bpmn:incoming>Flow_0pwtiqm</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
@ -61,83 +53,68 @@
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0jhpidf">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="152" y="281" width="36" height="36" />
|
||||
<dc:Bounds x="152" y="211" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1ees8ka_di" bpmnElement="SequenceFlow_1ees8ka">
|
||||
<di:waypoint x="188" y="299" />
|
||||
<di:waypoint x="230" y="299" />
|
||||
<di:waypoint x="188" y="229" />
|
||||
<di:waypoint x="230" y="229" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Activity_1k5eeun_di" bpmnElement="Activity_1k5eeun">
|
||||
<dc:Bounds x="460" y="84" width="100" height="80" />
|
||||
<dc:Bounds x="460" y="189" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1yqy50i_di" bpmnElement="Activity_1yqy50i">
|
||||
<dc:Bounds x="460" y="199" width="100" height="80" />
|
||||
<dc:Bounds x="460" y="80" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_16cm213_di" bpmnElement="Activity_16cm213">
|
||||
<dc:Bounds x="460" y="319" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0rbzgsm_di" bpmnElement="Activity_0rbzgsm">
|
||||
<dc:Bounds x="460" y="440" width="100" height="80" />
|
||||
<dc:Bounds x="460" y="300" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Gateway_1m22g4p_di" bpmnElement="Gateway_1nta7st">
|
||||
<dc:Bounds x="378" y="274" width="50" height="50" />
|
||||
<dc:Bounds x="378" y="204" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_1m8285h_di" bpmnElement="Flow_1m8285h">
|
||||
<di:waypoint x="403" y="274" />
|
||||
<di:waypoint x="403" y="239" />
|
||||
<di:waypoint x="460" y="239" />
|
||||
<di:waypoint x="403" y="204" />
|
||||
<di:waypoint x="403" y="120" />
|
||||
<di:waypoint x="460" y="120" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1nimppb_di" bpmnElement="Flow_1nimppb">
|
||||
<di:waypoint x="403" y="274" />
|
||||
<di:waypoint x="403" y="124" />
|
||||
<di:waypoint x="460" y="124" />
|
||||
<di:waypoint x="428" y="229" />
|
||||
<di:waypoint x="460" y="229" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_18pl92p_di" bpmnElement="Flow_18pl92p">
|
||||
<di:waypoint x="403" y="324" />
|
||||
<di:waypoint x="403" y="359" />
|
||||
<di:waypoint x="460" y="359" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_03u23vt_di" bpmnElement="Flow_03u23vt">
|
||||
<di:waypoint x="403" y="324" />
|
||||
<di:waypoint x="403" y="480" />
|
||||
<di:waypoint x="460" y="480" />
|
||||
<di:waypoint x="403" y="254" />
|
||||
<di:waypoint x="403" y="340" />
|
||||
<di:waypoint x="460" y="340" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Gateway_1kk6x70_di" bpmnElement="Gateway_12tpgcy">
|
||||
<dc:Bounds x="595" y="274" width="50" height="50" />
|
||||
<dc:Bounds x="595" y="204" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0pkxa8l_di" bpmnElement="Flow_0pkxa8l">
|
||||
<di:waypoint x="560" y="480" />
|
||||
<di:waypoint x="620" y="480" />
|
||||
<di:waypoint x="620" y="324" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Event_135x8jg_di" bpmnElement="Event_135x8jg">
|
||||
<dc:Bounds x="682" y="281" width="36" height="36" />
|
||||
<dc:Bounds x="682" y="211" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0pwtiqm_di" bpmnElement="Flow_0pwtiqm">
|
||||
<di:waypoint x="645" y="299" />
|
||||
<di:waypoint x="682" y="299" />
|
||||
<di:waypoint x="645" y="229" />
|
||||
<di:waypoint x="682" y="229" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0x9580l_di" bpmnElement="Flow_0x9580l">
|
||||
<di:waypoint x="560" y="359" />
|
||||
<di:waypoint x="620" y="359" />
|
||||
<di:waypoint x="620" y="324" />
|
||||
<di:waypoint x="560" y="340" />
|
||||
<di:waypoint x="620" y="340" />
|
||||
<di:waypoint x="620" y="254" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1txrak2_di" bpmnElement="Flow_1txrak2">
|
||||
<di:waypoint x="560" y="124" />
|
||||
<di:waypoint x="620" y="124" />
|
||||
<di:waypoint x="620" y="274" />
|
||||
<di:waypoint x="560" y="229" />
|
||||
<di:waypoint x="595" y="229" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1sggkit_di" bpmnElement="Flow_1sggkit">
|
||||
<di:waypoint x="560" y="239" />
|
||||
<di:waypoint x="620" y="239" />
|
||||
<di:waypoint x="620" y="274" />
|
||||
<di:waypoint x="560" y="120" />
|
||||
<di:waypoint x="620" y="120" />
|
||||
<di:waypoint x="620" y="204" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_024q2cw_di" bpmnElement="Flow_024q2cw">
|
||||
<di:waypoint x="330" y="299" />
|
||||
<di:waypoint x="378" y="299" />
|
||||
<di:waypoint x="330" y="229" />
|
||||
<di:waypoint x="378" y="229" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Activity_0vfs7g0_di" bpmnElement="Activity_00rh8pw">
|
||||
<dc:Bounds x="230" y="259" width="100" height="80" />
|
||||
<dc:Bounds x="230" y="189" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1p34ouw" name="DRD" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
||||
<decision id="should_enable_two_forms" name="should_enable_two_forms">
|
||||
<extensionElements>
|
||||
<biodi:bounds x="150" y="80" width="180" height="80" />
|
||||
</extensionElements>
|
||||
<decisionTable id="DecisionTable_15l972l">
|
||||
<input id="InputClause_0lms091" label="some_input">
|
||||
<inputExpression id="LiteralExpression_0ypio3f" typeRef="boolean" expressionLanguage="feel" />
|
||||
</input>
|
||||
<output id="OutputClause_1f7iind" label="two_forms" name="two_forms" typeRef="boolean" />
|
||||
<rule id="DecisionRule_0914coi">
|
||||
<inputEntry id="UnaryTests_1efs7cx">
|
||||
<text>false</text>
|
||||
</inputEntry>
|
||||
<outputEntry id="LiteralExpression_0utnzi4">
|
||||
<text>false</text>
|
||||
</outputEntry>
|
||||
</rule>
|
||||
<rule id="DecisionRule_0zcj74u">
|
||||
<inputEntry id="UnaryTests_0v2q8t3">
|
||||
<text>true</text>
|
||||
</inputEntry>
|
||||
<outputEntry id="LiteralExpression_1jh1u0c">
|
||||
<text>true</text>
|
||||
</outputEntry>
|
||||
</rule>
|
||||
</decisionTable>
|
||||
</decision>
|
||||
</definitions>
|
@ -3,7 +3,7 @@ from datetime import datetime, timezone
|
||||
from unittest.mock import patch, Mock
|
||||
|
||||
from crc import session
|
||||
from crc.models.api_models import WorkflowApiSchema
|
||||
from crc.models.api_models import WorkflowApiSchema, WorkflowApi
|
||||
from crc.models.study import StudyModel, StudyModelSchema
|
||||
from crc.models.protocol_builder import ProtocolBuilderStatus, ProtocolBuilderStudyDetailsSchema, \
|
||||
ProtocolBuilderStudySchema
|
||||
@ -160,9 +160,6 @@ class TestStudyApi(BaseTest):
|
||||
rv = self.app.delete('/v1.0/study/%i' % study.id)
|
||||
self.assert_failure(rv, error_code="study_integrity_error")
|
||||
|
||||
|
||||
|
||||
|
||||
def test_delete_workflow(self):
|
||||
self.load_example_data()
|
||||
study = session.query(StudyModel).first()
|
||||
@ -207,3 +204,56 @@ class TestStudyApi(BaseTest):
|
||||
json_data_after = json.loads(response_after.get_data(as_text=True))
|
||||
workflows_after = WorkflowApiSchema(many=True).load(json_data_after)
|
||||
self.assertEqual(1, len(workflows_after))
|
||||
|
||||
"""
|
||||
Workflow Specs that have been made available (or not) to a particular study via the status.bpmn should be flagged
|
||||
as available (or not) when the list of a study's workflows is retrieved.
|
||||
"""
|
||||
def test_workflow_spec_status(self):
|
||||
self.load_example_data()
|
||||
study = session.query(StudyModel).first()
|
||||
|
||||
# Add status workflow
|
||||
self.load_test_spec('status')
|
||||
|
||||
# Add status workflow to the study
|
||||
status_spec = session.query(WorkflowSpecModel).filter_by(is_status=True).first()
|
||||
add_status_response = self.app.post('/v1.0/study/%i/workflows' % study.id,
|
||||
content_type="application/json",
|
||||
headers=self.logged_in_headers(),
|
||||
data=json.dumps(WorkflowSpecModelSchema().dump(status_spec)))
|
||||
self.assert_success(add_status_response)
|
||||
json_data_status = json.loads(add_status_response.get_data(as_text=True))
|
||||
status_workflow: WorkflowApi = WorkflowApiSchema().load(json_data_status)
|
||||
status_task_id = status_workflow.next_task['id']
|
||||
|
||||
# Add all available non-status workflows to the study
|
||||
specs = session.query(WorkflowSpecModel).filter_by(is_status=False).all()
|
||||
for spec in specs:
|
||||
add_response = self.app.post('/v1.0/study/%i/workflows' % study.id,
|
||||
content_type="application/json",
|
||||
headers=self.logged_in_headers(),
|
||||
data=json.dumps(WorkflowSpecModelSchema().dump(spec)))
|
||||
self.assert_success(add_response)
|
||||
|
||||
for is_active in [False, True]:
|
||||
# Update status task data
|
||||
update_status_response = self.app.put('/v1.0/workflow/%i/task/%s/data' % (status_workflow.id, status_task_id),
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json",
|
||||
data=json.dumps({'some_input': is_active}))
|
||||
self.assert_success(update_status_response)
|
||||
|
||||
# List workflows for study
|
||||
response_after = self.app.get('/v1.0/study/%i/workflows' % study.id,
|
||||
content_type="application/json",
|
||||
headers=self.logged_in_headers())
|
||||
self.assert_success(response_after)
|
||||
|
||||
json_data_after = json.loads(response_after.get_data(as_text=True))
|
||||
workflows_after = WorkflowApiSchema(many=True).load(json_data_after)
|
||||
self.assertEqual(len(specs), len(workflows_after))
|
||||
|
||||
for workflow in workflows_after:
|
||||
self.assertEqual(workflow.is_active, is_active)
|
||||
|
||||
|
@ -326,6 +326,9 @@ class TestWorkflowProcessor(BaseTest):
|
||||
|
||||
def test_status_bpmn(self):
|
||||
self.load_example_data()
|
||||
|
||||
specs = session.query(WorkflowSpecModel).all()
|
||||
|
||||
study = session.query(StudyModel).first()
|
||||
workflow_spec_model = self.load_test_spec("status")
|
||||
|
||||
@ -345,6 +348,5 @@ class TestWorkflowProcessor(BaseTest):
|
||||
self.assertEqual(processor.get_status(), WorkflowStatus.complete)
|
||||
|
||||
# Enabled status of all specs should match the value set in the first task
|
||||
for spec_id in ['two_forms', 'random_fact', 'pb_responses', 'study_details']:
|
||||
self.assertEqual(task.data[spec_id], enabled)
|
||||
|
||||
for spec in specs:
|
||||
self.assertEqual(task.data[spec.id], enabled)
|
||||
|
Loading…
x
Reference in New Issue
Block a user