diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py index 1a4510b7..7af28170 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance.py @@ -34,36 +34,6 @@ class ProcessInstanceCannotBeDeletedError(Exception): """ProcessInstanceCannotBeDeletedError.""" -class NavigationItemSchema(Schema): - """NavigationItemSchema.""" - - class Meta: - """Meta.""" - - fields = [ - "spec_id", - "name", - "spec_type", - "task_id", - "description", - "backtracks", - "indent", - "lane", - "state", - "children", - ] - unknown = INCLUDE - - state = marshmallow.fields.String(required=False, allow_none=True) - description = marshmallow.fields.String(required=False, allow_none=True) - backtracks = marshmallow.fields.String(required=False, allow_none=True) - lane = marshmallow.fields.String(required=False, allow_none=True) - task_id = marshmallow.fields.String(required=False, allow_none=True) - children = marshmallow.fields.List( - marshmallow.fields.Nested(lambda: NavigationItemSchema()) - ) - - class ProcessInstanceStatus(SpiffEnum): """ProcessInstanceStatus.""" @@ -139,6 +109,10 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): """Validate_status.""" return self.validate_enum_field(key, value, ProcessInstanceStatus) + def can_submit_task(self) -> bool: + """Can_submit_task.""" + return not self.has_terminal_status() and self.status != "suspended" + def has_terminal_status(self) -> bool: """Has_terminal_status.""" return self.status in self.terminal_statuses() diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index f2cb3e12..349af266 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -1670,6 +1670,13 @@ def task_submit( """Task_submit_user_data.""" principal = find_principal_or_raise() process_instance = find_process_instance_by_id_or_raise(process_instance_id) + if not process_instance.can_submit_task(): + raise ApiError( + error_code="process_instance_not_runnable", + message=f"Process Instance ({process_instance.id}) has status " + f"{process_instance.status} which does not allow tasks to be submitted.", + status_code=400, + ) processor = ProcessInstanceProcessor(process_instance) spiff_task = get_spiff_task_from_process_instance( diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index fd9f7b85..4112c6e8 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -417,13 +417,15 @@ export default function ProcessModelShow() { }; const checkDuplicateFile = (event: any) => { - if (processModel && processModel.files.length > 0) { + if (processModel) { let foundExistingFile = false; - processModel.files.forEach((file) => { - if (file.name === filesToUpload[0].name) { - foundExistingFile = true; - } - }); + if (processModel.files.length > 0) { + processModel.files.forEach((file) => { + if (file.name === filesToUpload[0].name) { + foundExistingFile = true; + } + }); + } if (foundExistingFile) { displayOverwriteConfirmation(filesToUpload[0].name); setFileUploadEvent(event); @@ -431,12 +433,11 @@ export default function ProcessModelShow() { doFileUpload(event); } } + return null; }; const handleFileUpload = (event: any) => { - if (processModel) { - checkDuplicateFile(event); - } + checkDuplicateFile(event); setShowFileUploadModal(false); }; @@ -473,9 +474,6 @@ export default function ProcessModelShow() { }; const processModelFilesSection = () => { - if (!processModel) { - return null; - } return (