mirror of
https://github.com/sartography/spiffworkflow-backend.git
synced 2025-02-24 21:38:22 +00:00
Merge branch 'main' into cullerton
This commit is contained in:
commit
bb230b5447
6
.github/workflows/constraints.txt
vendored
6
.github/workflows/constraints.txt
vendored
@ -1,5 +1,5 @@
|
|||||||
pip==22.0.4
|
pip==22.1.2
|
||||||
nox==2022.1.7
|
nox==2022.1.7
|
||||||
nox-poetry==0.9.0
|
nox-poetry==1.0.1
|
||||||
poetry==1.1.13
|
poetry==1.1.13
|
||||||
virtualenv==20.14.1
|
virtualenv==20.15.0
|
||||||
|
@ -19,4 +19,8 @@ fi
|
|||||||
export FLASK_SESSION_SECRET_KEY=super_secret_key
|
export FLASK_SESSION_SECRET_KEY=super_secret_key
|
||||||
export APPLICATION_ROOT="/"
|
export APPLICATION_ROOT="/"
|
||||||
|
|
||||||
|
if [[ -n "${SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA:-}" ]]; then
|
||||||
./bin/boot_server_in_docker
|
./bin/boot_server_in_docker
|
||||||
|
else
|
||||||
|
FLASK_APP=src/spiffworkflow_backend poetry run flask run -p 7000
|
||||||
|
fi
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
furo==2022.4.7
|
furo==2022.6.21
|
||||||
sphinx==4.5.0
|
sphinx==5.0.2
|
||||||
sphinx-click==4.0.3
|
sphinx-click==4.2.0
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: ae997451b037
|
Revision ID: a650f4061955
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2022-06-24 13:47:56.423142
|
Create Date: 2022-06-28 15:15:08.319053
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'ae997451b037'
|
revision = 'a650f4061955'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
@ -88,6 +88,19 @@ def upgrade():
|
|||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('user_id', 'group_id', name='user_group_assignment_unique')
|
sa.UniqueConstraint('user_id', 'group_id', name='user_group_assignment_unique')
|
||||||
)
|
)
|
||||||
|
op.create_table('active_task',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('task_id', sa.String(length=50), nullable=False),
|
||||||
|
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('assigned_principal_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('process_instance_data', sa.Text(), nullable=True),
|
||||||
|
sa.Column('status', sa.String(length=50), nullable=False),
|
||||||
|
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['assigned_principal_id'], ['principal.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('task_id', 'process_instance_id', name='active_task_unique')
|
||||||
|
)
|
||||||
op.create_table('file',
|
op.create_table('file',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=50), nullable=False),
|
sa.Column('name', sa.String(length=50), nullable=False),
|
||||||
@ -149,6 +162,7 @@ def downgrade():
|
|||||||
op.drop_table('data_store')
|
op.drop_table('data_store')
|
||||||
op.drop_table('task_event')
|
op.drop_table('task_event')
|
||||||
op.drop_table('file')
|
op.drop_table('file')
|
||||||
|
op.drop_table('active_task')
|
||||||
op.drop_table('user_group_assignment')
|
op.drop_table('user_group_assignment')
|
||||||
op.drop_index(op.f('ix_process_instance_report_process_model_identifier'), table_name='process_instance_report')
|
op.drop_index(op.f('ix_process_instance_report_process_model_identifier'), table_name='process_instance_report')
|
||||||
op.drop_index(op.f('ix_process_instance_report_process_group_identifier'), table_name='process_instance_report')
|
op.drop_index(op.f('ix_process_instance_report_process_group_identifier'), table_name='process_instance_report')
|
20
poetry.lock
generated
20
poetry.lock
generated
@ -1550,7 +1550,7 @@ python-versions = ">=3.6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sphinx"
|
name = "sphinx"
|
||||||
version = "4.5.0"
|
version = "5.0.2"
|
||||||
description = "Python documentation generator"
|
description = "Python documentation generator"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@ -1560,7 +1560,7 @@ python-versions = ">=3.6"
|
|||||||
alabaster = ">=0.7,<0.8"
|
alabaster = ">=0.7,<0.8"
|
||||||
babel = ">=1.3"
|
babel = ">=1.3"
|
||||||
colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""}
|
colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""}
|
||||||
docutils = ">=0.14,<0.18"
|
docutils = ">=0.14,<0.19"
|
||||||
imagesize = "*"
|
imagesize = "*"
|
||||||
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
|
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
|
||||||
Jinja2 = ">=2.3"
|
Jinja2 = ">=2.3"
|
||||||
@ -1577,8 +1577,8 @@ sphinxcontrib-serializinghtml = ">=1.1.5"
|
|||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinxcontrib-websupport"]
|
docs = ["sphinxcontrib-websupport"]
|
||||||
lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"]
|
lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.950)", "docutils-stubs", "types-typed-ast", "types-requests"]
|
||||||
test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"]
|
test = ["pytest (>=4.6)", "html5lib", "cython", "typed-ast"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sphinx-autoapi"
|
name = "sphinx-autoapi"
|
||||||
@ -1848,7 +1848,7 @@ test = ["pytest", "typing-extensions", "mypy"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-pytz"
|
name = "types-pytz"
|
||||||
version = "2022.1.0"
|
version = "2022.1.1"
|
||||||
description = "Typing stubs for pytz"
|
description = "Typing stubs for pytz"
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
@ -2021,7 +2021,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "b62cf79b84095d7587533e0ac88c8be8a035e97dac57e521273f246bca78cf78"
|
content-hash = "5b14a72a62346e76294a4c854e48dac9c6d8ce353c5d6a269dc08635d008054f"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
alabaster = [
|
alabaster = [
|
||||||
@ -3033,8 +3033,8 @@ soupsieve = [
|
|||||||
{file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"},
|
{file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"},
|
||||||
]
|
]
|
||||||
sphinx = [
|
sphinx = [
|
||||||
{file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"},
|
{file = "Sphinx-5.0.2-py3-none-any.whl", hash = "sha256:d3e57663eed1d7c5c50895d191fdeda0b54ded6f44d5621b50709466c338d1e8"},
|
||||||
{file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"},
|
{file = "Sphinx-5.0.2.tar.gz", hash = "sha256:b18e978ea7565720f26019c702cd85c84376e948370f1cd43d60265010e1c7b0"},
|
||||||
]
|
]
|
||||||
sphinx-autoapi = [
|
sphinx-autoapi = [
|
||||||
{file = "sphinx-autoapi-1.8.4.tar.gz", hash = "sha256:8c4ec5fbedc1e6e8f4692bcc4fcd1abcfb9e8dfca8a4ded60ad811a743c22ccc"},
|
{file = "sphinx-autoapi-1.8.4.tar.gz", hash = "sha256:8c4ec5fbedc1e6e8f4692bcc4fcd1abcfb9e8dfca8a4ded60ad811a743c22ccc"},
|
||||||
@ -3187,8 +3187,8 @@ typeguard = [
|
|||||||
{file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"},
|
{file = "typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4"},
|
||||||
]
|
]
|
||||||
types-pytz = [
|
types-pytz = [
|
||||||
{file = "types-pytz-2022.1.0.tar.gz", hash = "sha256:bbe7eaf93b4fbec4780323af925286d265a6681f50dba57d16dbd8695c3ed63d"},
|
{file = "types-pytz-2022.1.1.tar.gz", hash = "sha256:4e7add70886dc2ee6ee7535c8184a26eeb0ac9dbafae9962cb882d74b9f67330"},
|
||||||
{file = "types_pytz-2022.1.0-py3-none-any.whl", hash = "sha256:20984c0c321d312caac8fd0a0b5456b615cb9cce74473624a794851a606fabae"},
|
{file = "types_pytz-2022.1.1-py3-none-any.whl", hash = "sha256:581467742f32f15fff1098698b11fd511057a2a8a7568d33b604083f2b03c24f"},
|
||||||
]
|
]
|
||||||
typing-extensions = [
|
typing-extensions = [
|
||||||
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
|
{file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
|
||||||
|
@ -44,7 +44,7 @@ marshmallow-enum = "^1.5.1"
|
|||||||
marshmallow-sqlalchemy = "^0.28.0"
|
marshmallow-sqlalchemy = "^0.28.0"
|
||||||
PyJWT = "^2.4.0"
|
PyJWT = "^2.4.0"
|
||||||
gunicorn = "^20.1.0"
|
gunicorn = "^20.1.0"
|
||||||
types-pytz = "^2022.1.0"
|
types-pytz = "^2022.1.1"
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
@ -54,7 +54,7 @@ safety = "^1.10.3"
|
|||||||
mypy = ">=0.961"
|
mypy = ">=0.961"
|
||||||
typeguard = "^2.13.2"
|
typeguard = "^2.13.2"
|
||||||
xdoctest = {extras = ["colors"], version = "^1.0.0"}
|
xdoctest = {extras = ["colors"], version = "^1.0.0"}
|
||||||
sphinx = "^4.3.0"
|
sphinx = "^5.0.2"
|
||||||
sphinx-autobuild = ">=2021.3.14"
|
sphinx-autobuild = ">=2021.3.14"
|
||||||
pre-commit = "^2.15.0"
|
pre-commit = "^2.15.0"
|
||||||
flake8 = "^4.0.1"
|
flake8 = "^4.0.1"
|
||||||
|
@ -552,6 +552,52 @@ paths:
|
|||||||
# '204':
|
# '204':
|
||||||
# description: The file was removed.
|
# description: The file was removed.
|
||||||
|
|
||||||
|
/tasks/my-tasks:
|
||||||
|
parameters:
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: The page number to return. Defaults to page 1.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: per_page
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: The page number to return. Defaults to page 1.
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
get:
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.task_list_my_tasks
|
||||||
|
summary: returns the list of ready or waiting tasks for a user
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: list of tasks
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
# $ref: "#/components/schemas/ActiveTask"
|
||||||
|
$ref: "#/components/schemas/Task"
|
||||||
|
/tasks/{task_id}:
|
||||||
|
parameters:
|
||||||
|
- name: task_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The unique id of an existing process group.
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
get:
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.task_show
|
||||||
|
summary: Gets one task that a user wants to complete
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: One task
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/Task"
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
jwt:
|
jwt:
|
||||||
|
@ -3,6 +3,7 @@ from typing import Any
|
|||||||
|
|
||||||
from flask_bpmn.models.db import db
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
|
||||||
|
|
||||||
@ -14,4 +15,10 @@ def find_or_create_user(username: str = "test_user1") -> Any:
|
|||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
principal = PrincipalModel.query.filter_by(user_id=user.id).first()
|
||||||
|
if principal is None:
|
||||||
|
principal = PrincipalModel(user_id=user.id)
|
||||||
|
db.session.add(principal)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
@ -4,6 +4,7 @@ autoflake8 will remove these lines without the noqa comment
|
|||||||
"""
|
"""
|
||||||
from flask_bpmn.models.db import add_listeners
|
from flask_bpmn.models.db import add_listeners
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.active_task import ActiveTaskModel # noqa: F401
|
||||||
from spiffworkflow_backend.models.data_store import DataStoreModel # noqa: F401
|
from spiffworkflow_backend.models.data_store import DataStoreModel # noqa: F401
|
||||||
from spiffworkflow_backend.models.file import FileModel # noqa: F401
|
from spiffworkflow_backend.models.file import FileModel # noqa: F401
|
||||||
from spiffworkflow_backend.models.principal import PrincipalModel # noqa: F401
|
from spiffworkflow_backend.models.principal import PrincipalModel # noqa: F401
|
||||||
|
32
src/spiffworkflow_backend/models/active_task.py
Normal file
32
src/spiffworkflow_backend/models/active_task.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
"""Active_task."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||||
|
from sqlalchemy import ForeignKey
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ActiveTaskModel(SpiffworkflowBaseDBModel):
|
||||||
|
"""ActiveTaskModel."""
|
||||||
|
|
||||||
|
__tablename__ = "active_task"
|
||||||
|
__table_args__ = (
|
||||||
|
db.UniqueConstraint(
|
||||||
|
"task_id", "process_instance_id", name="active_task_unique"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
|
task_id: str = db.Column(db.String(50), nullable=False)
|
||||||
|
process_instance_id: int = db.Column(db.Integer, nullable=False)
|
||||||
|
assigned_principal_id: int = db.Column(ForeignKey(PrincipalModel.id))
|
||||||
|
process_instance_data: str = db.Column(db.Text)
|
||||||
|
status: str = db.Column(db.String(50), nullable=False)
|
||||||
|
|
||||||
|
updated_at_in_seconds: int = db.Column(db.Integer)
|
||||||
|
created_at_in_seconds: int = db.Column(db.Integer)
|
@ -50,6 +50,7 @@ class FileType(SpiffEnum):
|
|||||||
docx = "docx"
|
docx = "docx"
|
||||||
gif = "gif"
|
gif = "gif"
|
||||||
jpg = "jpg"
|
jpg = "jpg"
|
||||||
|
json = "json"
|
||||||
md = "md"
|
md = "md"
|
||||||
pdf = "pdf"
|
pdf = "pdf"
|
||||||
png = "png"
|
png = "png"
|
||||||
@ -73,6 +74,7 @@ CONTENT_TYPES = {
|
|||||||
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||||
"gif": "image/gif",
|
"gif": "image/gif",
|
||||||
"jpg": "image/jpeg",
|
"jpg": "image/jpeg",
|
||||||
|
"json": "application/json",
|
||||||
"md": "text/plain",
|
"md": "text/plain",
|
||||||
"pdf": "application/pdf",
|
"pdf": "application/pdf",
|
||||||
"png": "image/png",
|
"png": "image/png",
|
||||||
|
@ -15,5 +15,5 @@ class PrincipalModel(SpiffworkflowBaseDBModel):
|
|||||||
__table_args__ = (CheckConstraint("NOT(user_id IS NULL AND group_id IS NULL)"),)
|
__table_args__ = (CheckConstraint("NOT(user_id IS NULL AND group_id IS NULL)"),)
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user_id = db.Column(ForeignKey(UserModel.id), nullable=True)
|
user_id = db.Column(ForeignKey(UserModel.id), nullable=True, unique=True)
|
||||||
group_id = db.Column(ForeignKey(GroupModel.id), nullable=True)
|
group_id = db.Column(ForeignKey(GroupModel.id), nullable=True, unique=True)
|
||||||
|
@ -12,6 +12,7 @@ from flask import url_for
|
|||||||
from flask_bpmn.models.db import db
|
from flask_bpmn.models.db import db
|
||||||
from werkzeug.wrappers.response import Response
|
from werkzeug.wrappers.response import Response
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.services.process_instance_processor import (
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
ProcessInstanceProcessor,
|
ProcessInstanceProcessor,
|
||||||
@ -41,6 +42,12 @@ def token() -> str:
|
|||||||
db.session.add(user)
|
db.session.add(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
principal = PrincipalModel.query.filter_by(user_id=user.id).first()
|
||||||
|
if principal is None:
|
||||||
|
principal = PrincipalModel(user_id=user.id)
|
||||||
|
db.session.add(principal)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
auth_token = user.encode_auth_token()
|
auth_token = user.encode_auth_token()
|
||||||
return f"auth_token: {auth_token}"
|
return f"auth_token: {auth_token}"
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ from flask_bpmn.models.db import db
|
|||||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||||
ProcessEntityNotFoundError,
|
ProcessEntityNotFoundError,
|
||||||
)
|
)
|
||||||
|
from spiffworkflow_backend.models.active_task import ActiveTaskModel
|
||||||
from spiffworkflow_backend.models.file import FileSchema
|
from spiffworkflow_backend.models.file import FileSchema
|
||||||
from spiffworkflow_backend.models.file import FileType
|
from spiffworkflow_backend.models.file import FileType
|
||||||
from spiffworkflow_backend.models.principal import PrincipalModel
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
@ -431,6 +432,59 @@ def process_instance_report(
|
|||||||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||||
|
|
||||||
|
|
||||||
|
def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Response:
|
||||||
|
"""Task_list_my_tasks."""
|
||||||
|
principal = PrincipalModel.query.filter_by(user_id=g.user.id).first()
|
||||||
|
if principal is None:
|
||||||
|
raise (
|
||||||
|
ApiError(
|
||||||
|
code="principal_not_found",
|
||||||
|
message=f"Principal not found from user id: {g.user.id}",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
active_tasks = (
|
||||||
|
ActiveTaskModel.query.filter_by(assigned_principal_id=principal.id)
|
||||||
|
.order_by(ActiveTaskModel.id.desc())
|
||||||
|
.paginate(page, per_page, False)
|
||||||
|
)
|
||||||
|
|
||||||
|
response_json = {
|
||||||
|
"results": active_tasks.items,
|
||||||
|
"pagination": {
|
||||||
|
"count": len(active_tasks.items),
|
||||||
|
"total": active_tasks.total,
|
||||||
|
"pages": active_tasks.pages,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return response_json
|
||||||
|
|
||||||
|
|
||||||
|
def task_show(task_id: int) -> flask.wrappers.Response:
|
||||||
|
"""Task_list_my_tasks."""
|
||||||
|
principal = PrincipalModel.query.filter_by(user_id=g.user.id).first()
|
||||||
|
if principal is None:
|
||||||
|
raise (
|
||||||
|
ApiError(
|
||||||
|
code="principal_not_found",
|
||||||
|
message=f"Principal not found from user id: {g.user.id}",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
active_task_assigned_to_me = ActiveTaskModel.query.filter_by(id=task_id, assigned_principal_id=principal.id).first()
|
||||||
|
if active_task_assigned_to_me is None:
|
||||||
|
raise (
|
||||||
|
ApiError(
|
||||||
|
code="task_not_found",
|
||||||
|
message=f"Task not found for principal user: {g.user.id} and id: {task_id}",
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return active_task_assigned_to_me
|
||||||
|
|
||||||
|
|
||||||
def get_file_from_request() -> Any:
|
def get_file_from_request() -> Any:
|
||||||
"""Get_file_from_request."""
|
"""Get_file_from_request."""
|
||||||
request_file = connexion.request.files.get("file")
|
request_file = connexion.request.files.get("file")
|
||||||
|
@ -30,10 +30,12 @@ from SpiffWorkflow.dmn.serializer import BusinessRuleTaskConverter # type: igno
|
|||||||
from SpiffWorkflow.exceptions import WorkflowTaskExecException # type: ignore
|
from SpiffWorkflow.exceptions import WorkflowTaskExecException # type: ignore
|
||||||
from SpiffWorkflow.serializer.exceptions import MissingSpecError # type: ignore
|
from SpiffWorkflow.serializer.exceptions import MissingSpecError # type: ignore
|
||||||
from SpiffWorkflow.specs import WorkflowSpec # type: ignore
|
from SpiffWorkflow.specs import WorkflowSpec # type: ignore
|
||||||
from SpiffWorkflow.task import Task # type: ignore
|
from SpiffWorkflow.task import Task
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.active_task import ActiveTaskModel # type: ignore
|
||||||
from spiffworkflow_backend.models.file import File
|
from spiffworkflow_backend.models.file import File
|
||||||
from spiffworkflow_backend.models.file import FileType
|
from spiffworkflow_backend.models.file import FileType
|
||||||
|
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
|
||||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||||
@ -331,6 +333,19 @@ class ProcessInstanceProcessor:
|
|||||||
self.process_instance_model.end_in_seconds = round(time.time())
|
self.process_instance_model.end_in_seconds = round(time.time())
|
||||||
|
|
||||||
db.session.add(self.process_instance_model)
|
db.session.add(self.process_instance_model)
|
||||||
|
|
||||||
|
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
|
||||||
|
for ready_or_waiting_task in ready_or_waiting_tasks:
|
||||||
|
active_task = ActiveTaskModel(
|
||||||
|
task_id=str(ready_or_waiting_task.id),
|
||||||
|
process_instance_id=self.process_instance_model.id,
|
||||||
|
# FIXME: look for the correct principal based on ready_or_waiting_task.lane
|
||||||
|
assigned_principal_id=PrincipalModel.query.first().id,
|
||||||
|
process_instance_data=json.dumps(self.get_data()),
|
||||||
|
status=ready_or_waiting_task.state.value,
|
||||||
|
)
|
||||||
|
db.session.add(active_task)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -555,6 +570,11 @@ class ProcessInstanceProcessor:
|
|||||||
and t.state in [TaskState.COMPLETED, TaskState.CANCELLED]
|
and t.state in [TaskState.COMPLETED, TaskState.CANCELLED]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_all_ready_or_waiting_tasks(self) -> list[Task]:
|
||||||
|
"""Get_all_ready_or_waiting_tasks."""
|
||||||
|
all_tasks = self.bpmn_process_instance.get_tasks(TaskState.ANY_MASK)
|
||||||
|
return [t for t in all_tasks if t.state in [TaskState.WAITING, TaskState.READY]]
|
||||||
|
|
||||||
def get_nav_item(self, task: Task) -> Any:
|
def get_nav_item(self, task: Task) -> Any:
|
||||||
"""Get_nav_item."""
|
"""Get_nav_item."""
|
||||||
for nav_item in self.bpmn_process_instance.get_nav_list():
|
for nav_item in self.bpmn_process_instance.get_nav_list():
|
||||||
|
@ -13,9 +13,6 @@ from spiffworkflow_backend.models.principal import PrincipalModel
|
|||||||
def test_user_can_be_given_permission_to_administer_process_group(app: Flask) -> None:
|
def test_user_can_be_given_permission_to_administer_process_group(app: Flask) -> None:
|
||||||
"""Test_user_can_be_given_permission_to_administer_process_group."""
|
"""Test_user_can_be_given_permission_to_administer_process_group."""
|
||||||
user = find_or_create_user()
|
user = find_or_create_user()
|
||||||
principal = PrincipalModel(user_id=user.id)
|
|
||||||
db.session.add(principal)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
# process_group = find_or_create_process_group()
|
# process_group = find_or_create_process_group()
|
||||||
# permission_target = PermissionTargetModel(process_group_id=process_group.id)
|
# permission_target = PermissionTargetModel(process_group_id=process_group.id)
|
||||||
|
2
wsgi.py
2
wsgi.py
@ -6,6 +6,8 @@ from spiffworkflow_backend.services.acceptance_test_fixtures import load_fixture
|
|||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
|
# this is in here because when we put it in the create_app function,
|
||||||
|
# it also loaded when we were running migrations, which resulted in a chicken/egg thing.
|
||||||
if os.environ.get("SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA") == "true":
|
if os.environ.get("SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA") == "true":
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
load_fixtures()
|
load_fixtures()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user