add an enum_label script that will return the label given a value selection.
This commit is contained in:
parent
1c84bd9f1b
commit
84ce24243f
|
@ -0,0 +1,85 @@
|
|||
from crc import db
|
||||
from crc.api.common import ApiError
|
||||
from crc.models.api_models import Task
|
||||
from crc.models.workflow import WorkflowModel
|
||||
from crc.scripts.script import Script
|
||||
from crc.services.lookup_service import LookupService
|
||||
from crc.services.workflow_processor import WorkflowProcessor
|
||||
|
||||
|
||||
class EnumLabel(Script):
|
||||
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
def get_description(self):
|
||||
return """In a form, when doing a select list, multi-select, autocomplete, etc... you are left with a single
|
||||
value. You may want to know the label that was displayed to the user as well. This will return the label, given
|
||||
enough information to do so, which requires the name of the user task, the name of the form field, and the value
|
||||
of the selected item.
|
||||
|
||||
Example:
|
||||
pet_label = enum_label('task_pet_form', 'pet', '1') // might return 'Dog' which has the value of 1
|
||||
"""
|
||||
|
||||
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
return self.do_task(task, study_id, workflow_id, *args, **kwargs)
|
||||
|
||||
def do_task(self, task, study_id, workflow_id, *args, **kwargs):
|
||||
|
||||
self.validate_arguments(**kwargs)
|
||||
|
||||
task_name = kwargs['task_name']
|
||||
field_name = kwargs['field']
|
||||
value = kwargs['value']
|
||||
|
||||
# get the field information for the provided task_name (NOT the current task)
|
||||
workflow_model = db.session.query(WorkflowModel).filter(WorkflowModel.id == workflow_id).first()
|
||||
processor = WorkflowProcessor(workflow_model)
|
||||
spec, field = processor.find_spec_and_field(task_name, field_name)
|
||||
print(spec)
|
||||
print(field)
|
||||
|
||||
if field.type == Task.FIELD_TYPE_AUTO_COMPLETE:
|
||||
return self.autocomplete_label(workflow_model, task_name, field, value)
|
||||
elif field.type == Task.FIELD_TYPE_ENUM and hasattr(field, 'options'):
|
||||
return self.enum_with_options_label(field, value)
|
||||
elif field.has_property(Task.FIELD_PROP_DATA_NAME):
|
||||
return self.enum_from_task_data_label(task, field, value)
|
||||
|
||||
def autocomplete_label(self, workflow_model, task_name, field, value):
|
||||
label_column = field.get_property(Task.FIELD_PROP_LABEL_COLUMN)
|
||||
result = LookupService().lookup(workflow_model, task_name, field.id, '', value=value, limit=1)
|
||||
if len(result) > 0:
|
||||
return result[0][label_column]
|
||||
else:
|
||||
return self.UNKNOWN
|
||||
|
||||
def enum_with_options_label(self, field, value):
|
||||
for option in field.options:
|
||||
if option.id == value:
|
||||
return option.name
|
||||
return self.UNKNOWN
|
||||
|
||||
def enum_from_task_data_label(self, task, field, value):
|
||||
data_name = field.get_property(Task.FIELD_PROP_DATA_NAME)
|
||||
value_column = field.get_property(Task.FIELD_PROP_VALUE_COLUMN)
|
||||
label_column = field.get_property(Task.FIELD_PROP_LABEL_COLUMN)
|
||||
if data_name in task.data:
|
||||
for d in task.data[data_name]:
|
||||
if d[value_column] == value:
|
||||
return d[label_column]
|
||||
return self.UNKNOWN
|
||||
|
||||
def validate_arguments(self, **kwargs):
|
||||
if len(kwargs) != 3:
|
||||
raise ApiError(code="invalid_argument",
|
||||
message="enum_label requires three arguments: Task id, Field id, and the selected value.")
|
||||
if not 'task_name' in kwargs:
|
||||
raise ApiError(code="invalid_argument",
|
||||
message="you must specify the 'task_name', that is the name of the task with a form and field")
|
||||
if not 'field' in kwargs:
|
||||
raise ApiError(code="invalid_argument",
|
||||
message="you must specify the 'field', that is the name of the field with an enum.")
|
||||
if not 'value' in kwargs:
|
||||
raise ApiError(code="invalid_argument",
|
||||
message="you must specify the 'value', that is the value of the enum you wish to get a label for.")
|
|
@ -85,7 +85,7 @@ class LookupService(object):
|
|||
|
||||
@staticmethod
|
||||
def lookup(workflow, task_spec_id, field_id, query, value=None, limit=10):
|
||||
|
||||
# Returns a list of dictionaries
|
||||
lookup_model = LookupService.__get_lookup_model(workflow, task_spec_id, field_id)
|
||||
|
||||
if lookup_model.is_ldap:
|
||||
|
|
|
@ -481,12 +481,21 @@ class WorkflowProcessor(object):
|
|||
for task in self.bpmn_workflow.get_ready_user_tasks():
|
||||
if task.workflow not in workflows:
|
||||
workflows.append(task.workflow)
|
||||
|
||||
spec_found = False
|
||||
for workflow in workflows:
|
||||
for spec in workflow.spec.task_specs.values():
|
||||
if spec.name == spec_name and hasattr(spec, "form"):
|
||||
if spec.name == spec_name:
|
||||
spec_found = True
|
||||
if not hasattr(spec, "form"):
|
||||
raise ApiError("invalid_spec",
|
||||
"The spec name you provided does not contain a form.")
|
||||
|
||||
for field in spec.form.fields:
|
||||
if field.id == field_id:
|
||||
return spec, field
|
||||
raise ApiError("invalid_field",
|
||||
"Unable to find a task in the workflow with a lookup field called: %s" % field_id)
|
||||
|
||||
raise ApiError("invalid_field",
|
||||
f"The task '{spec_name}' has no field named '{field_id}'")
|
||||
|
||||
raise ApiError("invalid_spec",
|
||||
f"Unable to find a task in the workflow called '{spec_name}'")
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
<?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:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_6e556e1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.10.0">
|
||||
<bpmn:process id="Process_6e556e1" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_173zivg</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_173zivg" sourceRef="StartEvent_1" targetRef="CreateDataSetup" />
|
||||
<bpmn:sequenceFlow id="Flow_1e3q669" sourceRef="CreateDataSetup" targetRef="myFormTask" />
|
||||
<bpmn:endEvent id="Event_03y3h9u">
|
||||
<bpmn:documentation># This is what was entered</bpmn:documentation>
|
||||
<bpmn:incoming>Flow_0f9fac8</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0f9fac8" sourceRef="myFormTask" targetRef="Event_03y3h9u" />
|
||||
<bpmn:scriptTask id="CreateDataSetup" name="Create Data Setup">
|
||||
<bpmn:incoming>Flow_173zivg</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1e3q669</bpmn:outgoing>
|
||||
<bpmn:script>dogs = [
|
||||
{'label':'Ham','value':'ham'},
|
||||
{'label':'Ginger','value':'ginger'},
|
||||
{'label':'Etta','value':'etta'},
|
||||
{'label':'Simo','value':'simo'},
|
||||
]
|
||||
|
||||
</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:userTask id="myFormTask" name="Render Form" camunda:formKey="my_form">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="ldap" label="LDAP Lookup" type="autocomplete">
|
||||
<camunda:properties>
|
||||
<camunda:property id="ldap.lookup" value="True" />
|
||||
<camunda:property id="value.column" value="uid" />
|
||||
<camunda:property id="label.column" value="display_name" />
|
||||
<camunda:property id="autocomplete_num" value="20" />
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="standard_enum" label="Standard Enum" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
<camunda:value id="one" name="1" />
|
||||
<camunda:value id="two" name="2" />
|
||||
<camunda:value id="three" name="3" />
|
||||
<camunda:value id="four" name="4" />
|
||||
<camunda:value id="five" name="5" />
|
||||
</camunda:formField>
|
||||
<camunda:formField id="spreadsheet" label="Spreadsheet" type="autocomplete">
|
||||
<camunda:properties>
|
||||
<camunda:property id="label.column" value="desc" />
|
||||
<camunda:property id="value.column" value="code" />
|
||||
<camunda:property id="spreadsheet.name" value="my_list.xlsx" />
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="data" label="My Data" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="data.name" value="dogs" />
|
||||
<camunda:property id="value.column" value="value" />
|
||||
<camunda:property id="label.column" value="label" />
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="checkbox" label="My Checkbox" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="enum_type" value="checkbox" />
|
||||
<camunda:property id="data.name" value="dogs" />
|
||||
<camunda:property id="value.column" value="value" />
|
||||
<camunda:property id="label.column" value="label" />
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="standard" label="Simple" type="string">
|
||||
<camunda:properties>
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="pets" label="Prefered Pet" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
<camunda:value id="cats" name="Cats" />
|
||||
<camunda:value id="dogs" name="Dogs" />
|
||||
<camunda:value id="other" name="other" />
|
||||
</camunda:formField>
|
||||
<camunda:formField id="petsOther" label="Prefered Pet (Other)" type="string">
|
||||
<camunda:properties>
|
||||
<camunda:property id="hide_expression" value="pets != 'other'" />
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
<camunda:formField id="file" label="upload file" type="file">
|
||||
<camunda:properties>
|
||||
<camunda:property id="repeat" value="repeatme" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_1e3q669</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0f9fac8</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_6e556e1">
|
||||
<bpmndi:BPMNEdge id="Flow_0f9fac8_di" bpmnElement="Flow_0f9fac8">
|
||||
<di:waypoint x="570" y="117" />
|
||||
<di:waypoint x="712" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1e3q669_di" bpmnElement="Flow_1e3q669">
|
||||
<di:waypoint x="370" y="117" />
|
||||
<di:waypoint x="470" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_173zivg_di" bpmnElement="Flow_173zivg">
|
||||
<di:waypoint x="215" y="117" />
|
||||
<di:waypoint x="270" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_03y3h9u_di" bpmnElement="Event_03y3h9u">
|
||||
<dc:Bounds x="712" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_13epga6_di" bpmnElement="CreateDataSetup">
|
||||
<dc:Bounds x="270" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1g2ib52_di" bpmnElement="myFormTask">
|
||||
<dc:Bounds x="470" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
Binary file not shown.
|
@ -0,0 +1,56 @@
|
|||
from tests.base_test import BaseTest
|
||||
|
||||
from crc.scripts.enum_label import EnumLabel
|
||||
from crc.api.common import ApiError
|
||||
|
||||
|
||||
class TestGetEnumLabel(BaseTest):
|
||||
|
||||
def setUp(self):
|
||||
self.load_example_data()
|
||||
self.workflow = self.create_workflow('enum_options_all')
|
||||
self.workflow_api = self.get_workflow_api(self.workflow)
|
||||
|
||||
# Assure the form has been loaded at least once.
|
||||
self.task = self.workflow_api.next_task
|
||||
self.assertEqual(self.task.name, 'myFormTask')
|
||||
|
||||
self.labelScript = EnumLabel()
|
||||
|
||||
def test_get_enum_label_for_ldap(self):
|
||||
result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='ldap', value='dhf8r')
|
||||
self.assertEqual("Dan Funk", result)
|
||||
|
||||
def test_get_enum_label_for_standard_enum(self):
|
||||
result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='standard_enum', value='one')
|
||||
self.assertEqual('1', result)
|
||||
|
||||
def test_get_enum_label_for_spreadsheet(self):
|
||||
result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='spreadsheet', value='2')
|
||||
self.assertEqual('T-shirts', result)
|
||||
|
||||
def test_get_enum_label_for_data(self):
|
||||
result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='data', value='simo')
|
||||
self.assertEqual('Simo', result)
|
||||
|
||||
def test_get_enum_label_for_checkbox(self):
|
||||
result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='checkbox', value='simo')
|
||||
self.assertEqual('Simo', result)
|
||||
|
||||
|
||||
def test_get_invalid_spec_name(self):
|
||||
with self.assertRaises(ApiError) as ctx:
|
||||
ldap_result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myWrongFormTask', field='standard_enum', value='one')
|
||||
self.assertEqual("ApiError: Unable to find a task in the workflow called 'myWrongFormTask'. ", str(ctx.exception))
|
||||
|
||||
def test_get_invalid_field_name(self):
|
||||
with self.assertRaises(ApiError) as ctx:
|
||||
ldap_result = self.labelScript.do_task(self.task, self.workflow_api.study_id, self.workflow_api.id,
|
||||
task_name='myFormTask', field='made_up_enum', value='one')
|
||||
self.assertEqual("ApiError: The task 'myFormTask' has no field named 'made_up_enum'. ", str(ctx.exception))
|
Loading…
Reference in New Issue