Squashed 'spiffworkflow-backend/' changes from 4f71a03e3..1b7c530a9
1b7c530a9 added some debug code for Processor failed to obtain task error w/ burnettk cf5bbf0e7 Merge commit 'ec431349e8b5cc2e8aa1ee1799bcb768fd3116c3' dfaa699f9 Merge pull request #7 from sartography/feature/get-local-time 3e1d6773e mypy 3471ab792 Added `get_localtime` script Added test for new script, with test process git-subtree-dir: spiffworkflow-backend git-subtree-split: 1b7c530a9ab2335a4a7b7efd1026464b333311aa
This commit is contained in:
parent
ec431349e8
commit
00dc4e149d
|
@ -20,7 +20,7 @@ groups:
|
|||
natalia,
|
||||
]
|
||||
|
||||
finance:
|
||||
Finance Team:
|
||||
users: [finance_user1]
|
||||
|
||||
permissions:
|
||||
|
@ -30,11 +30,24 @@ permissions:
|
|||
allowed_permissions: [create, read, update, delete, list, instantiate]
|
||||
uri: /*
|
||||
|
||||
finance-admin:
|
||||
groups: [finance]
|
||||
tasks-crud:
|
||||
groups: [everybody]
|
||||
users: []
|
||||
allowed_permissions: [create, read, update, delete]
|
||||
uri: /v1.0/process-groups/execute-procure-to-pay/*
|
||||
uri: /v1.0/tasks/*
|
||||
|
||||
# TODO: all uris should really have the same structure
|
||||
finance-admin-group:
|
||||
groups: ["Finance Team"]
|
||||
users: []
|
||||
allowed_permissions: [create, read, update, delete]
|
||||
uri: /v1.0/process-groups/finance/*
|
||||
|
||||
finance-admin-model:
|
||||
groups: ["Finance Team"]
|
||||
users: []
|
||||
allowed_permissions: [create, read, update, delete]
|
||||
uri: /v1.0/process-models/finance/*
|
||||
|
||||
read-all:
|
||||
groups: [finance, admin]
|
||||
|
|
|
@ -46,12 +46,12 @@ class ActiveTaskModel(SpiffworkflowBaseDBModel):
|
|||
updated_at_in_seconds: int = db.Column(db.Integer)
|
||||
created_at_in_seconds: int = db.Column(db.Integer)
|
||||
|
||||
task_id = db.Column(db.String(50))
|
||||
task_name = db.Column(db.String(50))
|
||||
task_title = db.Column(db.String(50))
|
||||
task_type = db.Column(db.String(50))
|
||||
task_status = db.Column(db.String(50))
|
||||
process_model_display_name = db.Column(db.String(255))
|
||||
task_id: str = db.Column(db.String(50))
|
||||
task_name: str = db.Column(db.String(50))
|
||||
task_title: str = db.Column(db.String(50))
|
||||
task_type: str = db.Column(db.String(50))
|
||||
task_status: str = db.Column(db.String(50))
|
||||
process_model_display_name: str = db.Column(db.String(255))
|
||||
|
||||
active_task_users = relationship("ActiveTaskUserModel", cascade="delete")
|
||||
potential_owners = relationship( # type: ignore
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import dataclasses
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
|
@ -1352,6 +1353,13 @@ def get_spiff_task_from_process_instance(
|
|||
task_uuid = uuid.UUID(task_id)
|
||||
spiff_task = processor.bpmn_process_instance.get_task(task_uuid)
|
||||
|
||||
# FOR DEBUGGING: save this variable so we get it in sentry when something fails
|
||||
active_task = ActiveTaskModel.query.filter_by(task_id=task_id).first()
|
||||
if active_task:
|
||||
task_json = dataclasses.asdict(active_task)
|
||||
print(f"task_json: {task_json}")
|
||||
########
|
||||
|
||||
if spiff_task is None:
|
||||
raise (
|
||||
ApiError(
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
from flask_bpmn.api.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.scripts.script import Script
|
||||
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
|
||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||
|
||||
|
||||
class GetLocaltime(Script):
|
||||
|
||||
def get_description(self) -> str:
|
||||
return """Converts a Datetime object into a Datetime object for a specific timezone.
|
||||
Defaults to US/Eastern"""
|
||||
|
||||
def run(
|
||||
self,
|
||||
task: Optional[SpiffTask],
|
||||
environment_identifier: str,
|
||||
*args: Any,
|
||||
**kwargs: Any
|
||||
) -> datetime:
|
||||
if len(args) > 0 or 'datetime' in kwargs:
|
||||
if 'datetime' in kwargs:
|
||||
date_time = kwargs['datetime']
|
||||
else:
|
||||
date_time = args[0]
|
||||
if 'timezone' in kwargs:
|
||||
timezone = kwargs['timezone']
|
||||
elif len(args) > 1:
|
||||
timezone = args[1]
|
||||
else:
|
||||
timezone = 'US/Eastern'
|
||||
localtime: datetime = date_time.astimezone(pytz.timezone(timezone))
|
||||
return localtime
|
||||
|
||||
else:
|
||||
raise ApiError(error_code='missing_datetime',
|
||||
message='You must include a datetime to convert.')
|
|
@ -20,10 +20,12 @@ class DataSetupService:
|
|||
failing_process_models = []
|
||||
process_models = ProcessModelService().get_process_models()
|
||||
for process_model in process_models:
|
||||
if process_model.primary_file_name:
|
||||
|
||||
process_model_files = SpecFileService.get_files(
|
||||
process_model, extension_filter=".bpmn"
|
||||
)
|
||||
for process_model_file in process_model_files:
|
||||
bpmn_xml_file_contents = SpecFileService.get_data(
|
||||
process_model, process_model.primary_file_name
|
||||
process_model, process_model_file.name
|
||||
)
|
||||
bad_files = [
|
||||
"B.1.0.bpmn",
|
||||
|
@ -32,21 +34,21 @@ class DataSetupService:
|
|||
"C.6.0.bpmn",
|
||||
"TC-5.1.bpmn",
|
||||
]
|
||||
if process_model.primary_file_name in bad_files:
|
||||
if process_model_file.name in bad_files:
|
||||
continue
|
||||
current_app.logger.debug(
|
||||
f"primary_file_name: {process_model.primary_file_name}"
|
||||
f"primary_file_name: {process_model_file.name}"
|
||||
)
|
||||
try:
|
||||
SpecFileService.update_file(
|
||||
process_model,
|
||||
process_model.primary_file_name,
|
||||
process_model_file.name,
|
||||
bpmn_xml_file_contents,
|
||||
)
|
||||
except Exception as ex:
|
||||
failing_process_models.append(
|
||||
(
|
||||
f"{process_model.process_group_id}/{process_model.id}/{process_model.primary_file_name}",
|
||||
f"{process_model.process_group_id}/{process_model.id}/{process_model_file.name}",
|
||||
str(ex),
|
||||
)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<?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:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="Proccess_LocalTime" name="Get LocalTime" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0ijucqh</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0ijucqh" sourceRef="StartEvent_1" targetRef="Activity_GetTimezone" />
|
||||
<bpmn:scriptTask id="Activity_GetTime" name="Get Time">
|
||||
<bpmn:documentation>Get Time</bpmn:documentation>
|
||||
<bpmn:incoming>Flow_10y2eax</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1gcfk27</bpmn:outgoing>
|
||||
<bpmn:script>some_time = datetime.now()
|
||||
localtime = get_localtime(some_time, timezone)</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:sequenceFlow id="Flow_1gcfk27" sourceRef="Activity_GetTime" targetRef="Activity_DisplayTime" />
|
||||
<bpmn:endEvent id="Event_1c50ix7">
|
||||
<bpmn:incoming>Flow_0dcc306</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0dcc306" sourceRef="Activity_DisplayTime" targetRef="Event_1c50ix7" />
|
||||
<bpmn:manualTask id="Activity_DisplayTime" name="Display Time">
|
||||
<bpmn:documentation>Display the time</bpmn:documentation>
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:instructionsForEndUser>## Time
|
||||
### Some Time: {{ some_time }}
|
||||
### Timezone: {{ timezone }}
|
||||
### Localtime: {{ localtime }}</spiffworkflow:instructionsForEndUser>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_1gcfk27</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0dcc306</bpmn:outgoing>
|
||||
</bpmn:manualTask>
|
||||
<bpmn:sequenceFlow id="Flow_10y2eax" sourceRef="Activity_GetTimezone" targetRef="Activity_GetTime" />
|
||||
<bpmn:userTask id="Activity_GetTimezone" name="Get Timezone">
|
||||
<bpmn:extensionElements>
|
||||
<spiffworkflow:properties>
|
||||
<spiffworkflow:property name="formJsonSchemaFilename" value="get_localtime.json" />
|
||||
</spiffworkflow:properties>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0ijucqh</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_10y2eax</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_LocalTime">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1ahvmya_di" bpmnElement="Activity_GetTime">
|
||||
<dc:Bounds x="430" y="137" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1c50ix7_di" bpmnElement="Event_1c50ix7">
|
||||
<dc:Bounds x="752" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1gfsyxd_di" bpmnElement="Activity_DisplayTime">
|
||||
<dc:Bounds x="590" y="137" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1x3u69s_di" bpmnElement="Activity_GetTimezone">
|
||||
<dc:Bounds x="270" y="137" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0ijucqh_di" bpmnElement="Flow_0ijucqh">
|
||||
<di:waypoint x="215" y="177" />
|
||||
<di:waypoint x="270" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1gcfk27_di" bpmnElement="Flow_1gcfk27">
|
||||
<di:waypoint x="530" y="177" />
|
||||
<di:waypoint x="590" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0dcc306_di" bpmnElement="Flow_0dcc306">
|
||||
<di:waypoint x="690" y="177" />
|
||||
<di:waypoint x="752" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_10y2eax_di" bpmnElement="Flow_10y2eax">
|
||||
<di:waypoint x="370" y="177" />
|
||||
<di:waypoint x="430" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"title": "Get Timezone",
|
||||
"description": "Form to select a timezone.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"timezone"
|
||||
],
|
||||
"properties": {
|
||||
"timezone": {
|
||||
"type": "string",
|
||||
"title": "Timezone",
|
||||
"enum": [
|
||||
"US/Eastern",
|
||||
"US/Pacific",
|
||||
"Europe/Berlin",
|
||||
"Australia/ACT"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import datetime
|
||||
import pytz
|
||||
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
|
||||
from spiffworkflow_backend.scripts.get_localtime import GetLocaltime
|
||||
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
||||
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
|
||||
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
||||
class TestGetLocaltime(BaseTest):
|
||||
"""TestProcessAPi."""
|
||||
|
||||
def test_get_localtime_script_directly(self) -> None:
|
||||
current_time = datetime.datetime.now()
|
||||
timezone = "US/Pacific"
|
||||
result = GetLocaltime().run(task=None, environment_identifier='testing', datetime=current_time, timezone=timezone)
|
||||
assert result == current_time.astimezone(pytz.timezone(timezone))
|
||||
|
||||
def test_get_localtime_script_through_bpmn(
|
||||
self,
|
||||
app: Flask,
|
||||
client: FlaskClient,
|
||||
with_db_and_bpmn_file_cleanup: None,
|
||||
) -> None:
|
||||
"""Test_process_instance_run."""
|
||||
initiator_user = self.find_or_create_user("initiator_user")
|
||||
process_model = load_test_spec(
|
||||
process_model_id="get_localtime", bpmn_file_name="get_localtime.bpmn"
|
||||
)
|
||||
process_instance = self.create_process_instance_from_process_model(
|
||||
process_model=process_model, user=initiator_user
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
processor.do_engine_steps(save=True)
|
||||
active_task = process_instance.active_tasks[0]
|
||||
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
|
||||
active_task.task_name, processor.bpmn_process_instance
|
||||
)
|
||||
|
||||
ProcessInstanceService.complete_form_task(
|
||||
processor, spiff_task, {"timezone": "US/Pacific"}, initiator_user
|
||||
)
|
||||
|
||||
active_task = process_instance.active_tasks[0]
|
||||
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
|
||||
active_task.task_name, processor.bpmn_process_instance
|
||||
)
|
||||
|
||||
assert spiff_task
|
||||
data = spiff_task.data
|
||||
some_time = data['some_time']
|
||||
localtime = data['localtime']
|
||||
timezone = data['timezone']
|
||||
|
||||
assert localtime == some_time.astimezone(pytz.timezone(timezone))
|
Loading…
Reference in New Issue