Merge remote-tracking branch 'origin/main' into new_report
This commit is contained in:
commit
57ddaff26c
|
@ -20,6 +20,12 @@ function get_python_dirs() {
|
||||||
(git ls-tree -r HEAD --name-only | grep -E '\.py$' | awk -F '/' '{print $1}' | sort | uniq | grep -v '\.' | grep -Ev '^(bin|migrations)$') || echo ''
|
(git ls-tree -r HEAD --name-only | grep -E '\.py$' | awk -F '/' '{print $1}' | sort | uniq | grep -v '\.' | grep -Ev '^(bin|migrations)$') || echo ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function run_fix_docstrings() {
|
||||||
|
if command -v fix_python_docstrings >/dev/null ; then
|
||||||
|
fix_python_docstrings $(get_top_level_directories_containing_python_files)
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function run_autoflake() {
|
function run_autoflake() {
|
||||||
if ! command -v autoflake8 >/dev/null ; then
|
if ! command -v autoflake8 >/dev/null ; then
|
||||||
pip install autoflake8
|
pip install autoflake8
|
||||||
|
@ -51,6 +57,7 @@ done
|
||||||
|
|
||||||
for python_project in "${python_projects[@]}" ; do
|
for python_project in "${python_projects[@]}" ; do
|
||||||
pushd "$python_project"
|
pushd "$python_project"
|
||||||
|
run_fix_docstrings || run_fix_docstrings
|
||||||
run_autoflake || run_autoflake
|
run_autoflake || run_autoflake
|
||||||
popd
|
popd
|
||||||
done
|
done
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: 568f5fe2c9f8
|
Revision ID: ff1c1628337c
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2022-11-24 12:11:46.669020
|
Create Date: 2022-11-28 15:08:52.014254
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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 = '568f5fe2c9f8'
|
revision = 'ff1c1628337c'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
@ -166,17 +166,6 @@ def upgrade():
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('key')
|
sa.UniqueConstraint('key')
|
||||||
)
|
)
|
||||||
op.create_table('spiff_step_details',
|
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('spiff_step', sa.Integer(), nullable=False),
|
|
||||||
sa.Column('task_json', sa.JSON(), nullable=False),
|
|
||||||
sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False),
|
|
||||||
sa.Column('completed_by_user_id', sa.Integer(), nullable=True),
|
|
||||||
sa.Column('lane_assignment_id', sa.Integer(), nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['lane_assignment_id'], ['group.id'], ),
|
|
||||||
sa.PrimaryKeyConstraint('id')
|
|
||||||
)
|
|
||||||
op.create_table('user_group_assignment',
|
op.create_table('user_group_assignment',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
|
@ -249,6 +238,29 @@ def upgrade():
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('principal_id', 'permission_target_id', 'permission', name='permission_assignment_uniq')
|
sa.UniqueConstraint('principal_id', 'permission_target_id', 'permission', name='permission_assignment_uniq')
|
||||||
)
|
)
|
||||||
|
op.create_table('process_instance_metadata',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('key', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('value', sa.String(length=255), nullable=False),
|
||||||
|
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('created_at_in_seconds', sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('process_instance_id', 'key', name='process_instance_metadata_unique')
|
||||||
|
)
|
||||||
|
op.create_table('spiff_step_details',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('spiff_step', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('task_json', sa.JSON(), nullable=False),
|
||||||
|
sa.Column('timestamp', sa.DECIMAL(precision=17, scale=6), nullable=False),
|
||||||
|
sa.Column('completed_by_user_id', sa.Integer(), nullable=True),
|
||||||
|
sa.Column('lane_assignment_id', sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['lane_assignment_id'], ['group.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
op.create_table('active_task_user',
|
op.create_table('active_task_user',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('active_task_id', sa.Integer(), nullable=False),
|
sa.Column('active_task_id', sa.Integer(), nullable=False),
|
||||||
|
@ -282,6 +294,8 @@ def downgrade():
|
||||||
op.drop_index(op.f('ix_active_task_user_user_id'), table_name='active_task_user')
|
op.drop_index(op.f('ix_active_task_user_user_id'), table_name='active_task_user')
|
||||||
op.drop_index(op.f('ix_active_task_user_active_task_id'), table_name='active_task_user')
|
op.drop_index(op.f('ix_active_task_user_active_task_id'), table_name='active_task_user')
|
||||||
op.drop_table('active_task_user')
|
op.drop_table('active_task_user')
|
||||||
|
op.drop_table('spiff_step_details')
|
||||||
|
op.drop_table('process_instance_metadata')
|
||||||
op.drop_table('permission_assignment')
|
op.drop_table('permission_assignment')
|
||||||
op.drop_table('message_instance')
|
op.drop_table('message_instance')
|
||||||
op.drop_index(op.f('ix_message_correlation_value'), table_name='message_correlation')
|
op.drop_index(op.f('ix_message_correlation_value'), table_name='message_correlation')
|
||||||
|
@ -291,7 +305,6 @@ def downgrade():
|
||||||
op.drop_table('message_correlation')
|
op.drop_table('message_correlation')
|
||||||
op.drop_table('active_task')
|
op.drop_table('active_task')
|
||||||
op.drop_table('user_group_assignment')
|
op.drop_table('user_group_assignment')
|
||||||
op.drop_table('spiff_step_details')
|
|
||||||
op.drop_table('secret')
|
op.drop_table('secret')
|
||||||
op.drop_table('refresh_token')
|
op.drop_table('refresh_token')
|
||||||
op.drop_index(op.f('ix_process_instance_report_identifier'), table_name='process_instance_report')
|
op.drop_index(op.f('ix_process_instance_report_identifier'), table_name='process_instance_report')
|
|
@ -136,47 +136,38 @@ permissions:
|
||||||
allowed_permissions: [create, read, update, delete]
|
allowed_permissions: [create, read, update, delete]
|
||||||
uri: /v1.0/process-groups/manage-procurement:procurement:*
|
uri: /v1.0/process-groups/manage-procurement:procurement:*
|
||||||
|
|
||||||
demo-models-instantiate-vendor-block:
|
manage-revenue-streams-instantiate:
|
||||||
groups: ["demo"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create]
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-block/process-instances
|
uri: /v1.0/process-models/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
demo-models-instantiate-vendor-change:
|
manage-revenue-streams-instances:
|
||||||
groups: ["demo"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-change/process-instances
|
uri: /v1.0/process-instances/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
demo-models-instantiate-vendor-creation:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-creation/process-instances
|
|
||||||
demo-models-instantiate-vendor-core-invoice_appoval:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:cc-invoice-approval/process-instances
|
|
||||||
demo-models-customer-contracts:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/process-instances
|
|
||||||
|
|
||||||
core-admin-models-instantiate:
|
manage-procurement-invoice-instantiate:
|
||||||
groups: ["core-contributor"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create]
|
||||||
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:cc-invoice-approval/process-instances
|
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
core-admin-instances:
|
manage-procurement-invoice-instances:
|
||||||
groups: ["core-contributor"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
core-admin-instances-slash:
|
|
||||||
groups: ["core-contributor"]
|
manage-procurement-instantiate:
|
||||||
|
groups: ["core-contributor", "demo"]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [create]
|
||||||
|
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
manage-procurement-instances:
|
||||||
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management/*
|
uri: /v1.0/process-instances/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
|
||||||
core1-admin-models-instantiate:
|
core1-admin-models-instantiate:
|
||||||
groups: ["core-contributor"]
|
groups: ["core-contributor"]
|
||||||
|
|
|
@ -136,44 +136,35 @@ permissions:
|
||||||
allowed_permissions: [create, read, update, delete]
|
allowed_permissions: [create, read, update, delete]
|
||||||
uri: /v1.0/process-groups/manage-procurement:procurement:*
|
uri: /v1.0/process-groups/manage-procurement:procurement:*
|
||||||
|
|
||||||
demo-models-instantiate-vendor-block:
|
manage-revenue-streams-instantiate:
|
||||||
groups: ["demo"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create]
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-block/process-instances
|
uri: /v1.0/process-models/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
demo-models-instantiate-vendor-change:
|
manage-revenue-streams-instances:
|
||||||
groups: ["demo"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-change/process-instances
|
uri: /v1.0/process-instances/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/*
|
||||||
demo-models-instantiate-vendor-creation:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:vendor-md-maintenance:vendor-md-creation/process-instances
|
|
||||||
demo-models-instantiate-vendor-core-invoice_appoval:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:cc-invoice-approval/process-instances
|
|
||||||
demo-models-customer-contracts:
|
|
||||||
groups: ["demo"]
|
|
||||||
users: []
|
|
||||||
allowed_permissions: [create]
|
|
||||||
uri: /v1.0/process-models/manage-revenue-streams:product-revenue-streams:customer-contracts-trade-terms/process-instances
|
|
||||||
|
|
||||||
core-admin-models-instantiate:
|
manage-procurement-invoice-instantiate:
|
||||||
groups: ["core-contributor"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create]
|
allowed_permissions: [create]
|
||||||
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:cc-invoice-approval/process-instances
|
uri: /v1.0/process-models/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
core-admin-instances:
|
manage-procurement-invoice-instances:
|
||||||
groups: ["core-contributor"]
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management:*
|
||||||
core-admin-instances-slash:
|
|
||||||
groups: ["core-contributor"]
|
manage-procurement-instantiate:
|
||||||
|
groups: ["core-contributor", "demo"]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [create]
|
||||||
|
uri: /v1.0/process-models/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
manage-procurement-instances:
|
||||||
|
groups: ["core-contributor", "demo"]
|
||||||
users: []
|
users: []
|
||||||
allowed_permissions: [create, read]
|
allowed_permissions: [create, read]
|
||||||
uri: /v1.0/process-instances/manage-procurement:procurement:core-contributor-invoice-management/*
|
uri: /v1.0/process-instances/manage-procurement:vendor-lifecycle-management:*
|
||||||
|
|
|
@ -51,5 +51,8 @@ from spiffworkflow_backend.models.spiff_step_details import (
|
||||||
) # noqa: F401
|
) # noqa: F401
|
||||||
from spiffworkflow_backend.models.user import UserModel # noqa: F401
|
from spiffworkflow_backend.models.user import UserModel # noqa: F401
|
||||||
from spiffworkflow_backend.models.group import GroupModel # noqa: F401
|
from spiffworkflow_backend.models.group import GroupModel # noqa: F401
|
||||||
|
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||||
|
ProcessInstanceMetadataModel,
|
||||||
|
) # noqa: F401
|
||||||
|
|
||||||
add_listeners()
|
add_listeners()
|
||||||
|
|
|
@ -22,6 +22,10 @@ from spiffworkflow_backend.models.task import TaskSchema
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessInstanceNotFoundError(Exception):
|
||||||
|
"""ProcessInstanceNotFoundError."""
|
||||||
|
|
||||||
|
|
||||||
class NavigationItemSchema(Schema):
|
class NavigationItemSchema(Schema):
|
||||||
"""NavigationItemSchema."""
|
"""NavigationItemSchema."""
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""Spiff_step_details."""
|
||||||
|
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.process_instance import ProcessInstanceModel
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProcessInstanceMetadataModel(SpiffworkflowBaseDBModel):
|
||||||
|
"""ProcessInstanceMetadataModel."""
|
||||||
|
|
||||||
|
__tablename__ = "process_instance_metadata"
|
||||||
|
__table_args__ = (
|
||||||
|
db.UniqueConstraint(
|
||||||
|
"process_instance_id", "key", name="process_instance_metadata_unique"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
|
process_instance_id: int = db.Column(
|
||||||
|
ForeignKey(ProcessInstanceModel.id), nullable=False # type: ignore
|
||||||
|
)
|
||||||
|
key: str = db.Column(db.String(255), nullable=False)
|
||||||
|
value: str = db.Column(db.String(255), nullable=False)
|
||||||
|
|
||||||
|
updated_at_in_seconds: int = db.Column(db.Integer, nullable=False)
|
||||||
|
created_at_in_seconds: int = db.Column(db.Integer, nullable=False)
|
|
@ -8,6 +8,7 @@ from sqlalchemy import ForeignKey
|
||||||
from sqlalchemy.orm import deferred
|
from sqlalchemy.orm import deferred
|
||||||
|
|
||||||
from spiffworkflow_backend.models.group import GroupModel
|
from spiffworkflow_backend.models.group import GroupModel
|
||||||
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -16,7 +17,9 @@ class SpiffStepDetailsModel(SpiffworkflowBaseDBModel):
|
||||||
|
|
||||||
__tablename__ = "spiff_step_details"
|
__tablename__ = "spiff_step_details"
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
process_instance_id: int = db.Column(db.Integer, nullable=False)
|
process_instance_id: int = db.Column(
|
||||||
|
ForeignKey(ProcessInstanceModel.id), nullable=False # type: ignore
|
||||||
|
)
|
||||||
spiff_step: int = db.Column(db.Integer, nullable=False)
|
spiff_step: int = db.Column(db.Integer, nullable=False)
|
||||||
task_json: str = deferred(db.Column(db.JSON, nullable=False)) # type: ignore
|
task_json: str = deferred(db.Column(db.JSON, nullable=False)) # type: ignore
|
||||||
timestamp: float = db.Column(db.DECIMAL(17, 6), nullable=False)
|
timestamp: float = db.Column(db.DECIMAL(17, 6), nullable=False)
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
"""Get_env."""
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from flask_bpmn.models.db import db
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||||
|
ProcessInstanceMetadataModel,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.models.script_attributes_context import (
|
||||||
|
ScriptAttributesContext,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.scripts.script import Script
|
||||||
|
|
||||||
|
|
||||||
|
class SaveProcessInstanceMetadata(Script):
|
||||||
|
"""SaveProcessInstanceMetadata."""
|
||||||
|
|
||||||
|
def get_description(self) -> str:
|
||||||
|
"""Get_description."""
|
||||||
|
return """Save a given dict as process instance metadata (useful for creating reports)."""
|
||||||
|
|
||||||
|
def run(
|
||||||
|
self,
|
||||||
|
script_attributes_context: ScriptAttributesContext,
|
||||||
|
*args: Any,
|
||||||
|
**kwargs: Any,
|
||||||
|
) -> Any:
|
||||||
|
"""Run."""
|
||||||
|
metadata_dict = args[0]
|
||||||
|
for key, value in metadata_dict.items():
|
||||||
|
pim = ProcessInstanceMetadataModel.query.filter_by(
|
||||||
|
process_instance_id=script_attributes_context.process_instance_id,
|
||||||
|
key=key,
|
||||||
|
).first()
|
||||||
|
if pim is None:
|
||||||
|
pim = ProcessInstanceMetadataModel(
|
||||||
|
process_instance_id=script_attributes_context.process_instance_id,
|
||||||
|
key=key,
|
||||||
|
)
|
||||||
|
pim.value = value
|
||||||
|
db.session.add(pim)
|
||||||
|
db.session.commit()
|
|
@ -590,16 +590,12 @@ class ProcessInstanceProcessor:
|
||||||
if self.bpmn_process_instance.is_completed():
|
if self.bpmn_process_instance.is_completed():
|
||||||
self.process_instance_model.end_in_seconds = round(time.time())
|
self.process_instance_model.end_in_seconds = round(time.time())
|
||||||
|
|
||||||
active_tasks = ActiveTaskModel.query.filter_by(
|
|
||||||
process_instance_id=self.process_instance_model.id
|
|
||||||
).all()
|
|
||||||
if len(active_tasks) > 0:
|
|
||||||
for at in active_tasks:
|
|
||||||
db.session.delete(at)
|
|
||||||
|
|
||||||
db.session.add(self.process_instance_model)
|
db.session.add(self.process_instance_model)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
active_tasks = ActiveTaskModel.query.filter_by(
|
||||||
|
process_instance_id=self.process_instance_model.id
|
||||||
|
).all()
|
||||||
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
|
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
|
||||||
for ready_or_waiting_task in ready_or_waiting_tasks:
|
for ready_or_waiting_task in ready_or_waiting_tasks:
|
||||||
# filter out non-usertasks
|
# filter out non-usertasks
|
||||||
|
@ -626,27 +622,41 @@ class ProcessInstanceProcessor:
|
||||||
if process_model_info is not None:
|
if process_model_info is not None:
|
||||||
process_model_display_name = process_model_info.display_name
|
process_model_display_name = process_model_info.display_name
|
||||||
|
|
||||||
active_task = ActiveTaskModel(
|
active_task = None
|
||||||
process_instance_id=self.process_instance_model.id,
|
for at in active_tasks:
|
||||||
process_model_display_name=process_model_display_name,
|
if at.task_id == str(ready_or_waiting_task.id):
|
||||||
form_file_name=form_file_name,
|
active_task = at
|
||||||
ui_form_file_name=ui_form_file_name,
|
active_tasks.remove(at)
|
||||||
task_id=str(ready_or_waiting_task.id),
|
|
||||||
task_name=ready_or_waiting_task.task_spec.name,
|
|
||||||
task_title=ready_or_waiting_task.task_spec.description,
|
|
||||||
task_type=ready_or_waiting_task.task_spec.__class__.__name__,
|
|
||||||
task_status=ready_or_waiting_task.get_state_name(),
|
|
||||||
lane_assignment_id=potential_owner_hash["lane_assignment_id"],
|
|
||||||
)
|
|
||||||
db.session.add(active_task)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
for potential_owner_id in potential_owner_hash["potential_owner_ids"]:
|
if active_task is None:
|
||||||
active_task_user = ActiveTaskUserModel(
|
active_task = ActiveTaskModel(
|
||||||
user_id=potential_owner_id, active_task_id=active_task.id
|
process_instance_id=self.process_instance_model.id,
|
||||||
|
process_model_display_name=process_model_display_name,
|
||||||
|
form_file_name=form_file_name,
|
||||||
|
ui_form_file_name=ui_form_file_name,
|
||||||
|
task_id=str(ready_or_waiting_task.id),
|
||||||
|
task_name=ready_or_waiting_task.task_spec.name,
|
||||||
|
task_title=ready_or_waiting_task.task_spec.description,
|
||||||
|
task_type=ready_or_waiting_task.task_spec.__class__.__name__,
|
||||||
|
task_status=ready_or_waiting_task.get_state_name(),
|
||||||
|
lane_assignment_id=potential_owner_hash["lane_assignment_id"],
|
||||||
)
|
)
|
||||||
db.session.add(active_task_user)
|
db.session.add(active_task)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
for potential_owner_id in potential_owner_hash[
|
||||||
|
"potential_owner_ids"
|
||||||
|
]:
|
||||||
|
active_task_user = ActiveTaskUserModel(
|
||||||
|
user_id=potential_owner_id, active_task_id=active_task.id
|
||||||
|
)
|
||||||
|
db.session.add(active_task_user)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
if len(active_tasks) > 0:
|
||||||
|
for at in active_tasks:
|
||||||
|
db.session.delete(at)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_parser() -> MyCustomParser:
|
def get_parser() -> MyCustomParser:
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?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: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="test_save_process_instance_metadata" isExecutable="true">
|
||||||
|
<bpmn:startEvent id="Event_0r6oru6">
|
||||||
|
<bpmn:outgoing>Flow_1j4jzft</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1j4jzft" sourceRef="Event_0r6oru6" targetRef="save_key1" />
|
||||||
|
<bpmn:endEvent id="Event_1s123jg">
|
||||||
|
<bpmn:incoming>Flow_01xr2ac</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:scriptTask id="save_key1">
|
||||||
|
<bpmn:incoming>Flow_1j4jzft</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_10xyk22</bpmn:outgoing>
|
||||||
|
<bpmn:script>save_process_instance_metadata({"key1": "value1"})</bpmn:script>
|
||||||
|
</bpmn:scriptTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_10xyk22" sourceRef="save_key1" targetRef="save_key2" />
|
||||||
|
<bpmn:scriptTask id="save_key2">
|
||||||
|
<bpmn:incoming>Flow_10xyk22</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_01xr2ac</bpmn:outgoing>
|
||||||
|
<bpmn:script>save_process_instance_metadata({"key2": "value2", "key3": "value3"})</bpmn:script>
|
||||||
|
</bpmn:scriptTask>
|
||||||
|
<bpmn:sequenceFlow id="Flow_01xr2ac" sourceRef="save_key2" targetRef="Event_1s123jg" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="test_save_process_instance_metadata">
|
||||||
|
<bpmndi:BPMNShape id="Event_0r6oru6_di" bpmnElement="Event_0r6oru6">
|
||||||
|
<dc:Bounds x="162" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0zfzev2_di" bpmnElement="save_key1">
|
||||||
|
<dc:Bounds x="250" y="140" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_0d1q8x4_di" bpmnElement="save_key2">
|
||||||
|
<dc:Bounds x="410" y="140" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Event_1s123jg_di" bpmnElement="Event_1s123jg">
|
||||||
|
<dc:Bounds x="582" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1j4jzft_di" bpmnElement="Flow_1j4jzft">
|
||||||
|
<di:waypoint x="198" y="180" />
|
||||||
|
<di:waypoint x="250" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_10xyk22_di" bpmnElement="Flow_10xyk22">
|
||||||
|
<di:waypoint x="350" y="180" />
|
||||||
|
<di:waypoint x="410" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_01xr2ac_di" bpmnElement="Flow_01xr2ac">
|
||||||
|
<di:waypoint x="510" y="180" />
|
||||||
|
<di:waypoint x="582" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
|
@ -0,0 +1,45 @@
|
||||||
|
"""Test_get_localtime."""
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||||
|
ProcessInstanceMetadataModel,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
|
ProcessInstanceProcessor,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSaveProcessInstanceMetadata(BaseTest):
|
||||||
|
"""TestSaveProcessInstanceMetadata."""
|
||||||
|
|
||||||
|
def test_can_save_process_instance_metadata(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_can_save_process_instance_metadata."""
|
||||||
|
initiator_user = self.find_or_create_user("initiator_user")
|
||||||
|
self.create_process_group(
|
||||||
|
client, with_super_admin_user, "test_group", "test_group"
|
||||||
|
)
|
||||||
|
process_model = load_test_spec(
|
||||||
|
process_model_id="save_process_instance_metadata/save_process_instance_metadata",
|
||||||
|
bpmn_file_name="save_process_instance_metadata.bpmn",
|
||||||
|
process_model_source_directory="save_process_instance_metadata",
|
||||||
|
)
|
||||||
|
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)
|
||||||
|
|
||||||
|
process_instance_metadata = ProcessInstanceMetadataModel.query.filter_by(
|
||||||
|
process_instance_id=process_instance.id
|
||||||
|
).all()
|
||||||
|
assert len(process_instance_metadata) == 3
|
|
@ -161,6 +161,7 @@ class TestProcessInstanceProcessor(BaseTest):
|
||||||
)
|
)
|
||||||
processor = ProcessInstanceProcessor(process_instance)
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
processor.do_engine_steps(save=True)
|
processor.do_engine_steps(save=True)
|
||||||
|
processor.save()
|
||||||
|
|
||||||
assert len(process_instance.active_tasks) == 1
|
assert len(process_instance.active_tasks) == 1
|
||||||
active_task = process_instance.active_tasks[0]
|
active_task = process_instance.active_tasks[0]
|
||||||
|
@ -241,3 +242,42 @@ class TestProcessInstanceProcessor(BaseTest):
|
||||||
)
|
)
|
||||||
|
|
||||||
assert process_instance.status == ProcessInstanceStatus.complete.value
|
assert process_instance.status == ProcessInstanceStatus.complete.value
|
||||||
|
|
||||||
|
def test_does_not_recreate_active_tasks_on_multiple_saves(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_sets_permission_correctly_on_active_task_when_using_dict."""
|
||||||
|
self.create_process_group(
|
||||||
|
client, with_super_admin_user, "test_group", "test_group"
|
||||||
|
)
|
||||||
|
initiator_user = self.find_or_create_user("initiator_user")
|
||||||
|
finance_user_three = self.find_or_create_user("testuser3")
|
||||||
|
assert initiator_user.principal is not None
|
||||||
|
assert finance_user_three.principal is not None
|
||||||
|
AuthorizationService.import_permissions_from_yaml_file()
|
||||||
|
|
||||||
|
finance_group = GroupModel.query.filter_by(identifier="Finance Team").first()
|
||||||
|
assert finance_group is not None
|
||||||
|
|
||||||
|
process_model = load_test_spec(
|
||||||
|
process_model_id="test_group/model_with_lanes",
|
||||||
|
bpmn_file_name="lanes_with_owner_dict.bpmn",
|
||||||
|
process_model_source_directory="model_with_lanes",
|
||||||
|
)
|
||||||
|
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)
|
||||||
|
assert len(process_instance.active_tasks) == 1
|
||||||
|
initial_active_task_id = process_instance.active_tasks[0].id
|
||||||
|
|
||||||
|
# save again to ensure we go attempt to process the active tasks again
|
||||||
|
processor.save()
|
||||||
|
|
||||||
|
assert len(process_instance.active_tasks) == 1
|
||||||
|
assert initial_active_task_id == process_instance.active_tasks[0].id
|
||||||
|
|
|
@ -81,6 +81,7 @@ export default function ProcessModelListTiles({
|
||||||
<div className="tile-process-group-content-container">
|
<div className="tile-process-group-content-container">
|
||||||
<div className="tile-title-top">
|
<div className="tile-title-top">
|
||||||
<a
|
<a
|
||||||
|
title={row.id}
|
||||||
data-qa="process-model-show-link"
|
data-qa="process-model-show-link"
|
||||||
href={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
href={`/admin/process-models/${modifyProcessIdentifierForPathParam(
|
||||||
row.id
|
row.id
|
||||||
|
|
Loading…
Reference in New Issue