diff --git a/Pipfile.lock b/Pipfile.lock index 5276b25a..04883073 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -783,7 +783,7 @@ "spiffworkflow": { "editable": true, "git": "https://github.com/sartography/SpiffWorkflow.git", - "ref": "976ac8b28f8168666efef7b4f0ec819f4a7dece1" + "ref": "ecd3f64d96886ea9e2c03242bc2ded9b10821e88" }, "sqlalchemy": { "hashes": [ diff --git a/crc/models/api_models.py b/crc/models/api_models.py index 794f927c..0e8f454a 100644 --- a/crc/models/api_models.py +++ b/crc/models/api_models.py @@ -1,3 +1,5 @@ +import enum + import marshmallow from marshmallow import INCLUDE from marshmallow_enum import EnumField @@ -6,13 +8,21 @@ from crc import ma from crc.models.workflow import WorkflowStatus +class MultiInstanceType(enum.Enum): + none = "none" + looping = "looping" + parallel = "parallel" + sequential = "sequential" + + class Task(object): ENUM_OPTIONS_FILE_PROP = "enum.options.file" EMUM_OPTIONS_VALUE_COL_PROP = "enum.options.value.column" EMUM_OPTIONS_LABEL_COL_PROP = "enum.options.label.column" - def __init__(self, id, name, title, type, state, form, documentation, data, is_multi_instance, mi_count, mi_index): + def __init__(self, id, name, title, type, state, form, documentation, data, + mi_type, mi_count, mi_index): self.id = id self.name = name self.title = title @@ -21,7 +31,7 @@ class Task(object): self.form = form self.documentation = documentation self.data = data - self.is_multi_instance = is_multi_instance + self.mi_type = mi_type self.mi_count = mi_count self.mi_index = mi_index @@ -59,9 +69,10 @@ class FormSchema(ma.Schema): class TaskSchema(ma.Schema): class Meta: - fields = ["id", "name", "title", "type", "state", "form", "documentation", "data", "is_multi_instance", + fields = ["id", "name", "title", "type", "state", "form", "documentation", "data", "mi_type", "mi_count", "mi_index"] + mi_type = EnumField(MultiInstanceType) documentation = marshmallow.fields.String(required=False, allow_none=True) form = marshmallow.fields.Nested(FormSchema, required=False, allow_none=True) title = marshmallow.fields.String(required=False, allow_none=True) diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index d058b3c6..0bffbfd9 100644 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -9,7 +9,7 @@ from SpiffWorkflow.specs import CancelTask, StartTask from pandas import ExcelFile from crc.api.common import ApiError -from crc.models.api_models import Task +from crc.models.api_models import Task, MultiInstanceType import jinja2 from jinja2 import Template @@ -69,13 +69,15 @@ class WorkflowService(object): else: task_type = "NoneTask" - multi_instance = isinstance(spiff_task.task_spec, MultiInstanceTask) - mi_count = 0 - mi_index = 0 - if multi_instance: - mi_count = spiff_task.task_spec._get_count(spiff_task) - mi_index = int(spiff_task._get_internal_data('runtimes', 1)) - + info = spiff_task.task_info() + if info["is_looping"]: + mi_type = MultiInstanceType.looping + elif info["is_sequential_mi"]: + mi_type = MultiInstanceType.sequential + elif info["is_parallel_mi"]: + mi_type = MultiInstanceType.parallel + else: + mi_type = MultiInstanceType.none task = Task(spiff_task.id, spiff_task.task_spec.name, @@ -85,11 +87,9 @@ class WorkflowService(object): None, "", spiff_task.data, - multi_instance, - mi_count, - mi_index) - - + mi_type, + info["mi_count"], + info["mi_index"]) # Only process the form and documentation if this is something that is ready or completed. if not (spiff_task._is_predicted()): diff --git a/tests/test_tasks_api.py b/tests/test_tasks_api.py index 39eb3d66..c8bbf1bc 100644 --- a/tests/test_tasks_api.py +++ b/tests/test_tasks_api.py @@ -3,7 +3,7 @@ import os from unittest.mock import patch from crc import session, app -from crc.models.api_models import WorkflowApiSchema +from crc.models.api_models import WorkflowApiSchema, MultiInstanceType from crc.models.file import FileModelSchema from crc.models.stats import WorkflowStatsModel, TaskEventModel from crc.models.workflow import WorkflowStatus @@ -272,7 +272,7 @@ class TestTasksApi(BaseTest): tasks = self.get_workflow_api(workflow).user_tasks self.assertEquals(1, len(tasks)) self.assertEquals("UserTask", tasks[0].type) - self.assertTrue(tasks[0].is_multi_instance) + self.assertEquals(MultiInstanceType.sequential, tasks[0].mi_type) self.assertEquals(3, tasks[0].mi_count) workflow_api = self.complete_form(workflow, tasks[0], {"name": "Dan"}) diff --git a/tests/test_workflow_processor_multi_instance.py b/tests/test_workflow_processor_multi_instance.py index 7fc921c6..d3ab4b06 100644 --- a/tests/test_workflow_processor_multi_instance.py +++ b/tests/test_workflow_processor_multi_instance.py @@ -8,6 +8,7 @@ from SpiffWorkflow.bpmn.specs.EndEvent import EndEvent from crc import session, db, app from crc.api.common import ApiError +from crc.models.api_models import MultiInstanceType from crc.models.file import FileModel, FileDataModel, CONTENT_TYPES from crc.models.study import StudyModel from crc.models.workflow import WorkflowSpecModel, WorkflowStatus, WorkflowModel @@ -35,7 +36,6 @@ class TestWorkflowProcessorMultiInstance(BaseTest): mock_get.return_value.ok = True mock_get.return_value.text = self.protocol_builder_response('investigators.json') - self.load_example_data() workflow_spec_model = self.load_test_spec("multi_instance") study = session.query(StudyModel).first() @@ -62,6 +62,7 @@ class TestWorkflowProcessorMultiInstance(BaseTest): self.assertEqual("MutiInstanceTask", task.get_name()) api_task = WorkflowService.spiff_task_to_api_task(task) + self.assertEquals(MultiInstanceType.sequential, api_task.mi_type) self.assertEquals(3, api_task.mi_count) self.assertEquals(1, api_task.mi_index) task.update_data({"email":"asd3v@virginia.edu"})