diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/scripts/get_localtime.py b/spiffworkflow-backend/src/spiffworkflow_backend/scripts/get_localtime.py new file mode 100644 index 000000000..0c7a30649 --- /dev/null +++ b/spiffworkflow-backend/src/spiffworkflow_backend/scripts/get_localtime.py @@ -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.') diff --git a/spiffworkflow-backend/tests/data/get_localtime/get_localtime.bpmn b/spiffworkflow-backend/tests/data/get_localtime/get_localtime.bpmn new file mode 100644 index 000000000..5660ba0bc --- /dev/null +++ b/spiffworkflow-backend/tests/data/get_localtime/get_localtime.bpmn @@ -0,0 +1,79 @@ + + + + + Flow_0ijucqh + + + + Get Time + Flow_10y2eax + Flow_1gcfk27 + some_time = datetime.now() +localtime = get_localtime(some_time, timezone) + + + + Flow_0dcc306 + + + + Display the time + + ## Time +### Some Time: {{ some_time }} +### Timezone: {{ timezone }} +### Localtime: {{ localtime }} + + Flow_1gcfk27 + Flow_0dcc306 + + + + + + + + + Flow_0ijucqh + Flow_10y2eax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spiffworkflow-backend/tests/data/get_localtime/get_localtime.json b/spiffworkflow-backend/tests/data/get_localtime/get_localtime.json new file mode 100644 index 000000000..e451f3ce4 --- /dev/null +++ b/spiffworkflow-backend/tests/data/get_localtime/get_localtime.json @@ -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" + ] + } + } +} \ No newline at end of file diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/scripts/test_get_localtime.py b/spiffworkflow-backend/tests/spiffworkflow_backend/scripts/test_get_localtime.py new file mode 100644 index 000000000..9110f736c --- /dev/null +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/scripts/test_get_localtime.py @@ -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))