commit
018ff47ba9
|
@ -22,10 +22,12 @@ from crc import session, app
|
|||
from crc.api.common import ApiError
|
||||
from crc.models.file import FileDataModel, FileModel, FileType
|
||||
from crc.models.task_event import TaskEventModel
|
||||
from crc.models.user import UserModelSchema
|
||||
from crc.models.workflow import WorkflowStatus, WorkflowModel, WorkflowSpecDependencyFile
|
||||
from crc.scripts.script import Script
|
||||
from crc.services.file_service import FileService
|
||||
from crc import app
|
||||
from crc.services.user_service import UserService
|
||||
|
||||
|
||||
class CustomBpmnScriptEngine(BpmnScriptEngine):
|
||||
|
@ -167,10 +169,18 @@ class WorkflowProcessor(object):
|
|||
spec = None
|
||||
|
||||
self.workflow_spec_id = workflow_model.workflow_spec_id
|
||||
|
||||
try:
|
||||
self.bpmn_workflow = self.__get_bpmn_workflow(workflow_model, spec, validate_only)
|
||||
self.bpmn_workflow.script_engine = self._script_engine
|
||||
|
||||
if UserService.has_user():
|
||||
current_user = UserService.current_user(allow_admin_impersonate=True)
|
||||
current_user_data = UserModelSchema().dump(current_user)
|
||||
tasks = self.bpmn_workflow.get_tasks(SpiffTask.READY)
|
||||
for task in tasks:
|
||||
task.data['current_user'] = current_user_data
|
||||
|
||||
if self.WORKFLOW_ID_KEY not in self.bpmn_workflow.data:
|
||||
if not workflow_model.id:
|
||||
session.add(workflow_model)
|
||||
|
|
|
@ -158,7 +158,9 @@ class WorkflowService(object):
|
|||
if field.has_property(Task.FIELD_PROP_HIDE_EXPRESSION) and field.has_validation(Task.FIELD_CONSTRAINT_REQUIRED):
|
||||
if not field.has_property(Task.FIELD_PROP_VALUE_EXPRESSION) or not (hasattr(field, 'default_value')):
|
||||
raise ApiError(code='hidden and required field missing default',
|
||||
message='Fields that are required but can be hidden must have either a default value or a value_expression')
|
||||
message='Fields that are required but can be hidden must have either a default value or a value_expression',
|
||||
task_id='task.id',
|
||||
task_name=task.get_name())
|
||||
|
||||
# If the field is hidden and not required, it should not produce a value.
|
||||
if field.has_property(Task.FIELD_PROP_HIDE_EXPRESSION) and not field.has_validation(Task.FIELD_CONSTRAINT_REQUIRED):
|
||||
|
@ -212,7 +214,7 @@ class WorkflowService(object):
|
|||
if not id[0].isalpha():
|
||||
return False
|
||||
for char in id[1:len(id)]:
|
||||
if char.isalnum() or char == '_':
|
||||
if char.isalnum() or char == '_' or char == '.':
|
||||
pass
|
||||
else:
|
||||
return False
|
||||
|
@ -510,9 +512,6 @@ class WorkflowService(object):
|
|||
# not be a previously completed MI Task.
|
||||
if add_docs_and_forms:
|
||||
task.data = spiff_task.data
|
||||
if UserService.has_user():
|
||||
current_user = UserService.current_user(allow_admin_impersonate=True)
|
||||
task.data['current_user'] = UserModelSchema().dump(current_user)
|
||||
if hasattr(spiff_task.task_spec, "form"):
|
||||
task.form = spiff_task.task_spec.form
|
||||
for i, field in enumerate(task.form.fields):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?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" id="Definitions_06dpn07" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.2.0">
|
||||
<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" id="Definitions_06dpn07" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.5.0">
|
||||
<bpmn:process id="Process_1iqn8uk" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0dbfi6t</bpmn:outgoing>
|
||||
|
@ -8,16 +8,16 @@
|
|||
<bpmn:manualTask id="Activity_09rr8u7" name="Hello">
|
||||
<bpmn:documentation><H1>Hello</H1></bpmn:documentation>
|
||||
<bpmn:incoming>Flow_0dbfi6t</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_02rje6r</bpmn:outgoing>
|
||||
<bpmn:outgoing>SequenceFlow_0o1egpu</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:sequenceFlow id="Flow_02rje6r" sourceRef="Activity_09rr8u7" targetRef="Activity_GetName" />
|
||||
<bpmn:userTask id="Activity_GetName" name="Get Name" camunda:formKey="GetName">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="name" label="Name" type="string" defaultValue="World" />
|
||||
<camunda:formField id="me.name" label="Enter" type="string" />
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_02rje6r</bpmn:incoming>
|
||||
<bpmn:incoming>SequenceFlow_1hytves</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1iphrck</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:sequenceFlow id="Flow_1iphrck" sourceRef="Activity_GetName" targetRef="Activity_GetTitle" />
|
||||
|
@ -40,47 +40,61 @@
|
|||
<bpmn:incoming>Flow_0hbiuz4</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0hbiuz4" sourceRef="Activity_SayHello" targetRef="Event_13veu8t" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0o1egpu" sourceRef="Activity_09rr8u7" targetRef="Task_SeedData" />
|
||||
<bpmn:scriptTask id="Task_SeedData" name="Seed Data">
|
||||
<bpmn:incoming>SequenceFlow_0o1egpu</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_1hytves</bpmn:outgoing>
|
||||
<bpmn:script>me = {'name': 'my_name'}</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1hytves" sourceRef="Task_SeedData" targetRef="Activity_GetName" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1iqn8uk">
|
||||
<bpmndi:BPMNEdge id="Flow_0dbfi6t_di" bpmnElement="Flow_0dbfi6t">
|
||||
<di:waypoint x="215" y="117" />
|
||||
<di:waypoint x="270" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_02rje6r_di" bpmnElement="Flow_02rje6r">
|
||||
<di:waypoint x="370" y="117" />
|
||||
<di:waypoint x="430" y="117" />
|
||||
<di:waypoint x="195" y="117" />
|
||||
<di:waypoint x="250" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1iphrck_di" bpmnElement="Flow_1iphrck">
|
||||
<di:waypoint x="530" y="117" />
|
||||
<di:waypoint x="590" y="117" />
|
||||
<di:waypoint x="660" y="117" />
|
||||
<di:waypoint x="720" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0cxh51h_di" bpmnElement="Flow_0cxh51h">
|
||||
<di:waypoint x="690" y="117" />
|
||||
<di:waypoint x="750" y="117" />
|
||||
<di:waypoint x="820" y="117" />
|
||||
<di:waypoint x="880" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0hbiuz4_di" bpmnElement="Flow_0hbiuz4">
|
||||
<di:waypoint x="850" y="117" />
|
||||
<di:waypoint x="912" y="117" />
|
||||
<di:waypoint x="980" y="117" />
|
||||
<di:waypoint x="1042" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="99" width="36" height="36" />
|
||||
<dc:Bounds x="159" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_132twgr_di" bpmnElement="Activity_09rr8u7">
|
||||
<dc:Bounds x="270" y="77" width="100" height="80" />
|
||||
<dc:Bounds x="250" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0it9qzi_di" bpmnElement="Activity_GetName">
|
||||
<dc:Bounds x="430" y="77" width="100" height="80" />
|
||||
<dc:Bounds x="560" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_19s9l3h_di" bpmnElement="Activity_GetTitle">
|
||||
<dc:Bounds x="590" y="77" width="100" height="80" />
|
||||
<dc:Bounds x="720" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_05qpklh_di" bpmnElement="Activity_SayHello">
|
||||
<dc:Bounds x="750" y="77" width="100" height="80" />
|
||||
<dc:Bounds x="880" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_13veu8t_di" bpmnElement="Event_13veu8t">
|
||||
<dc:Bounds x="912" y="99" width="36" height="36" />
|
||||
<dc:Bounds x="1042" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_0o1egpu_di" bpmnElement="SequenceFlow_0o1egpu">
|
||||
<di:waypoint x="350" y="117" />
|
||||
<di:waypoint x="410" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="ScriptTask_09ok9u2_di" bpmnElement="Task_SeedData">
|
||||
<dc:Bounds x="410" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1hytves_di" bpmnElement="SequenceFlow_1hytves">
|
||||
<di:waypoint x="510" y="117" />
|
||||
<di:waypoint x="560" y="117" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
|
|
|
@ -12,3 +12,14 @@ class TestFormFieldName(BaseTest):
|
|||
self.assertEqual(json_data[0]['message'],
|
||||
'When populating all fields ... Invalid Field name: "user-title". A field ID must begin '
|
||||
'with a letter, and can only contain letters, numbers, and "_"')
|
||||
|
||||
def test_form_field_name_with_period(self):
|
||||
workflow = self.create_workflow('workflow_form_field_name')
|
||||
|
||||
workflow_api = self.get_workflow_api(workflow)
|
||||
first_task = workflow_api.next_task
|
||||
self.complete_form(workflow_api, first_task, {})
|
||||
|
||||
workflow_api = self.get_workflow_api(workflow)
|
||||
second_task = workflow_api.next_task
|
||||
self.assertEqual('me.name', second_task.form['fields'][1]['id'])
|
||||
|
|
|
@ -12,6 +12,8 @@ class TestWorkflowHiddenRequiredField(BaseTest):
|
|||
|
||||
json_data = json.loads(rv.get_data(as_text=True))
|
||||
self.assertEqual(json_data[0]['code'], 'hidden and required field missing default')
|
||||
self.assertIn('task_id', json_data[0])
|
||||
self.assertIn('task_name', json_data[0])
|
||||
|
||||
def test_default_used(self):
|
||||
# If a field is hidden and required, make sure we use the default value
|
||||
|
|
Loading…
Reference in New Issue