Pi summary field (#1830)

* added summary column to process instance w/ burnettk

* minor fix for summary report w/ burnettk

* force pi summary to 255 characters max w/ burnettk

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-06-26 16:09:06 -04:00 committed by GitHub
parent 5c8b8619b7
commit bcb124813d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 71 additions and 4 deletions

View File

@ -0,0 +1,34 @@
"""empty message
Revision ID: ffef09e6ddf1
Revises: fc5815a9d482
Create Date: 2024-06-26 14:22:42.317828
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ffef09e6ddf1'
down_revision = 'fc5815a9d482'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('process_instance', schema=None) as batch_op:
batch_op.add_column(sa.Column('summary', sa.String(length=255), nullable=True))
batch_op.create_index(batch_op.f('ix_process_instance_summary'), ['summary'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('process_instance', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_process_instance_summary'))
batch_op.drop_column('summary')
# ### end Alembic commands ###

View File

@ -50,6 +50,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
id: int = db.Column(db.Integer, primary_key=True)
process_model_identifier: str = db.Column(db.String(255), nullable=False, index=True)
process_model_display_name: str = db.Column(db.String(255), nullable=False, index=True)
summary: str | None = db.Column(db.String(255), nullable=True, index=True)
process_initiator_id: int = db.Column(ForeignKey(UserModel.id), nullable=False, index=True) # type: ignore
bpmn_process_definition_id: int | None = db.Column(
ForeignKey(BpmnProcessDefinitionModel.id), # type: ignore
@ -151,6 +152,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
"process_model_identifier": self.process_model_identifier,
"start_in_seconds": self.start_in_seconds,
"status": self.status,
"summary": self.summary,
"task_updated_at_in_seconds": self.task_updated_at_in_seconds,
"updated_at_in_seconds": self.updated_at_in_seconds,
}

View File

@ -972,7 +972,12 @@ class ProcessInstanceProcessor:
)
pim.value = str(data_for_key)[0:255]
db.session.add(pim)
db.session.commit()
def update_summary(self) -> None:
current_data = self.get_current_data()
if "spiff_process_instance_summary" in current_data:
summary = current_data["spiff_process_instance_summary"]
self.process_instance_model.summary = summary[:255]
@classmethod
def _store_bpmn_process_definition(
@ -1119,6 +1124,7 @@ class ProcessInstanceProcessor:
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
self.extract_metadata()
self.update_summary()
for ready_or_waiting_task in ready_or_waiting_tasks:
# filter out non-usertasks

View File

@ -255,7 +255,6 @@ class ProcessInstanceReportService:
metadata_columns: list[ReportMetadataColumn],
) -> list[dict]:
results = []
cls.non_metadata_columns()
for process_instance_row in process_instance_sqlalchemy_rows:
process_instance_mapping = process_instance_row._mapping
process_instance_dict = process_instance_row[0].serialized()
@ -335,7 +334,7 @@ class ProcessInstanceReportService:
@classmethod
def non_metadata_columns(cls) -> list[str]:
return cls.process_instance_stock_columns() + ["process_initiator_username", "last_milestone_bpmn_name"]
return cls.process_instance_stock_columns() + ["process_initiator_username", "last_milestone_bpmn_name", "summary"]
@classmethod
def builtin_column_options(cls) -> list[ReportMetadataColumn]:

View File

@ -16,7 +16,8 @@
</bpmn:extensionElements>
<bpmn:incoming>Flow_0jml23i</bpmn:incoming>
<bpmn:outgoing>Flow_0ula2mv</bpmn:outgoing>
<bpmn:script>a = 1</bpmn:script>
<bpmn:script>a = 1
spiff_process_instance_summary = "WE SUMMARIZE"</bpmn:script>
</bpmn:scriptTask>
<bpmn:scriptTask id="script_two" name="script two">
<bpmn:extensionElements>
@ -24,6 +25,8 @@
</bpmn:extensionElements>
<bpmn:incoming>Flow_0ula2mv</bpmn:incoming>
<bpmn:outgoing>Flow_0xzoduo</bpmn:outgoing>
<bpmn:script>b = 2
spiff_process_instance_summary = "WE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAINWE SUMMARIZE AGAIN"</bpmn:script>
</bpmn:scriptTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">

View File

@ -1053,3 +1053,26 @@ class TestProcessInstanceProcessor(BaseTest):
processor.do_engine_steps(save=True)
assert process_instance.status == "complete"
def test_can_store_summary(
self,
app: Flask,
client: FlaskClient,
with_db_and_bpmn_file_cleanup: None,
) -> None:
process_model = load_test_spec(
process_model_id="test_group/script_task_with_instruction",
bpmn_file_name="script_task_with_instruction.bpmn",
process_model_source_directory="script-task-with-instruction",
)
process_instance = self.create_process_instance_from_process_model(process_model=process_model)
processor = ProcessInstanceProcessor(process_instance)
processor.do_engine_steps(save=True, execution_strategy_name="queue_instructions_for_end_user")
assert process_instance.summary is None
processor.do_engine_steps(save=True, execution_strategy_name="run_current_ready_tasks")
assert process_instance.summary == "WE SUMMARIZE"
processor.do_engine_steps(save=True, execution_strategy_name="greedy")
assert process_instance.summary is not None
# mypy thinks this is unreachable but it is reachable. summary can be str | None
assert len(process_instance.summary) == 255 # type: ignore