can somewhat search now w/ burnettk

This commit is contained in:
jasquat 2023-04-26 11:06:01 -04:00
parent 3984aa16aa
commit 8ac5f0228f
4 changed files with 494 additions and 391 deletions

View File

@ -68,9 +68,9 @@ from spiffworkflow_backend.services.process_instance_queue_service import (
from spiffworkflow_backend.services.process_instance_queue_service import ( from spiffworkflow_backend.services.process_instance_queue_service import (
ProcessInstanceQueueService, ProcessInstanceQueueService,
) )
from spiffworkflow_backend.services.process_instance_report_service import ( # from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportFilter, # ProcessInstanceReportFilter,
) # )
from spiffworkflow_backend.services.process_instance_report_service import ( from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportService, ProcessInstanceReportService,
) )

View File

@ -37,71 +37,71 @@ class ProcessInstanceReportNotFoundError(Exception):
"""ProcessInstanceReportNotFoundError.""" """ProcessInstanceReportNotFoundError."""
@dataclass # @dataclass
class ProcessInstanceReportFilter: # class ProcessInstanceReportFilter:
"""ProcessInstanceReportFilter.""" # """ProcessInstanceReportFilter."""
#
process_model_identifier: Optional[str] = None # process_model_identifier: Optional[str] = None
user_group_identifier: Optional[str] = None # user_group_identifier: Optional[str] = None
start_from: Optional[int] = None # start_from: Optional[int] = None
start_to: Optional[int] = None # start_to: Optional[int] = None
end_from: Optional[int] = None # end_from: Optional[int] = None
end_to: Optional[int] = None # end_to: Optional[int] = None
process_status: Optional[list[str]] = None # process_status: Optional[list[str]] = None
initiated_by_me: Optional[bool] = None # initiated_by_me: Optional[bool] = None
has_terminal_status: Optional[bool] = None # has_terminal_status: Optional[bool] = None
has_active_status: Optional[bool] = None # has_active_status: Optional[bool] = None
with_tasks_completed_by_me: Optional[bool] = None # with_tasks_completed_by_me: Optional[bool] = None
with_tasks_i_can_complete: Optional[bool] = None # with_tasks_i_can_complete: Optional[bool] = None
with_tasks_assigned_to_my_group: Optional[bool] = None # with_tasks_assigned_to_my_group: Optional[bool] = None
with_relation_to_me: Optional[bool] = None # with_relation_to_me: Optional[bool] = None
process_initiator_username: Optional[str] = None # process_initiator_username: Optional[str] = None
report_column_list: Optional[list] = None # report_column_list: Optional[list] = None
report_filter_by_list: Optional[list] = None # report_filter_by_list: Optional[list] = None
oldest_open_human_task_fields: Optional[list] = None # oldest_open_human_task_fields: Optional[list] = None
#
def to_dict(self) -> dict[str, str]: # def to_dict(self) -> dict[str, str]:
"""To_dict.""" # """To_dict."""
d = {} # d = {}
#
if self.process_model_identifier is not None: # if self.process_model_identifier is not None:
d["process_model_identifier"] = self.process_model_identifier # d["process_model_identifier"] = self.process_model_identifier
if self.user_group_identifier is not None: # if self.user_group_identifier is not None:
d["user_group_identifier"] = self.user_group_identifier # d["user_group_identifier"] = self.user_group_identifier
if self.start_from is not None: # if self.start_from is not None:
d["start_from"] = str(self.start_from) # d["start_from"] = str(self.start_from)
if self.start_to is not None: # if self.start_to is not None:
d["start_to"] = str(self.start_to) # d["start_to"] = str(self.start_to)
if self.end_from is not None: # if self.end_from is not None:
d["end_from"] = str(self.end_from) # d["end_from"] = str(self.end_from)
if self.end_to is not None: # if self.end_to is not None:
d["end_to"] = str(self.end_to) # d["end_to"] = str(self.end_to)
if self.process_status is not None: # if self.process_status is not None:
d["process_status"] = ",".join(self.process_status) # d["process_status"] = ",".join(self.process_status)
if self.initiated_by_me is not None: # if self.initiated_by_me is not None:
d["initiated_by_me"] = str(self.initiated_by_me).lower() # d["initiated_by_me"] = str(self.initiated_by_me).lower()
if self.has_terminal_status is not None: # if self.has_terminal_status is not None:
d["has_terminal_status"] = str(self.has_terminal_status).lower() # d["has_terminal_status"] = str(self.has_terminal_status).lower()
if self.has_active_status is not None: # if self.has_active_status is not None:
d["has_active_status"] = str(self.has_active_status).lower() # d["has_active_status"] = str(self.has_active_status).lower()
if self.with_tasks_completed_by_me is not None: # if self.with_tasks_completed_by_me is not None:
d["with_tasks_completed_by_me"] = str(self.with_tasks_completed_by_me).lower() # d["with_tasks_completed_by_me"] = str(self.with_tasks_completed_by_me).lower()
if self.with_tasks_i_can_complete is not None: # if self.with_tasks_i_can_complete is not None:
d["with_tasks_i_can_complete"] = str(self.with_tasks_i_can_complete).lower() # d["with_tasks_i_can_complete"] = str(self.with_tasks_i_can_complete).lower()
if self.with_tasks_assigned_to_my_group is not None: # if self.with_tasks_assigned_to_my_group is not None:
d["with_tasks_assigned_to_my_group"] = str(self.with_tasks_assigned_to_my_group).lower() # d["with_tasks_assigned_to_my_group"] = str(self.with_tasks_assigned_to_my_group).lower()
if self.with_relation_to_me is not None: # if self.with_relation_to_me is not None:
d["with_relation_to_me"] = str(self.with_relation_to_me).lower() # d["with_relation_to_me"] = str(self.with_relation_to_me).lower()
if self.process_initiator_username is not None: # if self.process_initiator_username is not None:
d["process_initiator_username"] = str(self.process_initiator_username) # d["process_initiator_username"] = str(self.process_initiator_username)
if self.report_column_list is not None: # if self.report_column_list is not None:
d["report_column_list"] = str(self.report_column_list) # d["report_column_list"] = str(self.report_column_list)
if self.report_filter_by_list is not None: # if self.report_filter_by_list is not None:
d["report_filter_by_list"] = str(self.report_filter_by_list) # d["report_filter_by_list"] = str(self.report_filter_by_list)
if self.oldest_open_human_task_fields is not None: # if self.oldest_open_human_task_fields is not None:
d["oldest_open_human_task_fields"] = str(self.oldest_open_human_task_fields) # d["oldest_open_human_task_fields"] = str(self.oldest_open_human_task_fields)
#
return d # return d
class ProcessInstanceReportService: class ProcessInstanceReportService:
@ -268,141 +268,141 @@ class ProcessInstanceReportService:
return process_instance_report # type: ignore return process_instance_report # type: ignore
@classmethod # @classmethod
def filter_by_to_dict(cls, process_instance_report: ProcessInstanceReportModel) -> dict[str, str]: # def filter_by_to_dict(cls, process_instance_report: ProcessInstanceReportModel) -> dict[str, str]:
"""Filter_by_to_dict.""" # """Filter_by_to_dict."""
metadata = process_instance_report.report_metadata # metadata = process_instance_report.report_metadata
filter_by = metadata.get("filter_by", []) # filter_by = metadata.get("filter_by", [])
filters = {d["field_name"]: d["field_value"] for d in filter_by if "field_name" in d and "field_value" in d} # filters = {d["field_name"]: d["field_value"] for d in filter_by if "field_name" in d and "field_value" in d}
return filters # return filters
#
@classmethod # @classmethod
def filter_from_metadata(cls, process_instance_report: ProcessInstanceReportModel) -> ProcessInstanceReportFilter: # def filter_from_metadata(cls, process_instance_report: ProcessInstanceReportModel) -> ProcessInstanceReportFilter:
"""Filter_from_metadata.""" # """Filter_from_metadata."""
filters = cls.filter_by_to_dict(process_instance_report) # filters = cls.filter_by_to_dict(process_instance_report)
#
def bool_value(key: str) -> Optional[bool]: # def bool_value(key: str) -> Optional[bool]:
"""Bool_value.""" # """Bool_value."""
if key not in filters: # if key not in filters:
return None # return None
# bool returns True if not an empty string so check explicitly for false # # bool returns True if not an empty string so check explicitly for false
if filters[key] in ["false", "False"]: # if filters[key] in ["false", "False"]:
return False # return False
return bool(filters[key]) # return bool(filters[key])
#
def int_value(key: str) -> Optional[int]: # def int_value(key: str) -> Optional[int]:
"""Int_value.""" # """Int_value."""
return int(filters[key]) if key in filters else None # return int(filters[key]) if key in filters else None
#
def list_value(key: str) -> Optional[list[str]]: # def list_value(key: str) -> Optional[list[str]]:
return filters[key].split(",") if key in filters else None # return filters[key].split(",") if key in filters else None
#
process_model_identifier = filters.get("process_model_identifier") # process_model_identifier = filters.get("process_model_identifier")
user_group_identifier = filters.get("user_group_identifier") # user_group_identifier = filters.get("user_group_identifier")
start_from = int_value("start_from") # start_from = int_value("start_from")
start_to = int_value("start_to") # start_to = int_value("start_to")
end_from = int_value("end_from") # end_from = int_value("end_from")
end_to = int_value("end_to") # end_to = int_value("end_to")
process_status = list_value("process_status") # process_status = list_value("process_status")
initiated_by_me = bool_value("initiated_by_me") # initiated_by_me = bool_value("initiated_by_me")
has_terminal_status = bool_value("has_terminal_status") # has_terminal_status = bool_value("has_terminal_status")
has_active_status = bool_value("has_active_status") # has_active_status = bool_value("has_active_status")
with_tasks_completed_by_me = bool_value("with_tasks_completed_by_me") # with_tasks_completed_by_me = bool_value("with_tasks_completed_by_me")
with_tasks_i_can_complete = bool_value("with_tasks_i_can_complete") # with_tasks_i_can_complete = bool_value("with_tasks_i_can_complete")
with_tasks_assigned_to_my_group = bool_value("with_tasks_assigned_to_my_group") # with_tasks_assigned_to_my_group = bool_value("with_tasks_assigned_to_my_group")
with_relation_to_me = bool_value("with_relation_to_me") # with_relation_to_me = bool_value("with_relation_to_me")
process_initiator_username = filters.get("process_initiator_username") # process_initiator_username = filters.get("process_initiator_username")
report_column_list = list_value("report_column_list") # report_column_list = list_value("report_column_list")
report_filter_by_list = list_value("report_filter_by_list") # report_filter_by_list = list_value("report_filter_by_list")
oldest_open_human_task_fields = list_value("oldest_open_human_task_fields") # oldest_open_human_task_fields = list_value("oldest_open_human_task_fields")
#
report_filter = ProcessInstanceReportFilter( # report_filter = ProcessInstanceReportFilter(
process_model_identifier=process_model_identifier, # process_model_identifier=process_model_identifier,
user_group_identifier=user_group_identifier, # user_group_identifier=user_group_identifier,
start_from=start_from, # start_from=start_from,
start_to=start_to, # start_to=start_to,
end_from=end_from, # end_from=end_from,
end_to=end_to, # end_to=end_to,
process_status=process_status, # process_status=process_status,
initiated_by_me=initiated_by_me, # initiated_by_me=initiated_by_me,
has_terminal_status=has_terminal_status, # has_terminal_status=has_terminal_status,
has_active_status=has_active_status, # has_active_status=has_active_status,
with_tasks_completed_by_me=with_tasks_completed_by_me, # with_tasks_completed_by_me=with_tasks_completed_by_me,
with_tasks_i_can_complete=with_tasks_i_can_complete, # with_tasks_i_can_complete=with_tasks_i_can_complete,
with_tasks_assigned_to_my_group=with_tasks_assigned_to_my_group, # with_tasks_assigned_to_my_group=with_tasks_assigned_to_my_group,
with_relation_to_me=with_relation_to_me, # with_relation_to_me=with_relation_to_me,
process_initiator_username=process_initiator_username, # process_initiator_username=process_initiator_username,
report_column_list=report_column_list, # report_column_list=report_column_list,
report_filter_by_list=report_filter_by_list, # report_filter_by_list=report_filter_by_list,
oldest_open_human_task_fields=oldest_open_human_task_fields, # oldest_open_human_task_fields=oldest_open_human_task_fields,
) # )
#
return report_filter # return report_filter
#
@classmethod # @classmethod
def filter_from_metadata_with_overrides( # def filter_from_metadata_with_overrides(
cls, # cls,
process_instance_report: ProcessInstanceReportModel, # process_instance_report: ProcessInstanceReportModel,
process_model_identifier: Optional[str] = None, # process_model_identifier: Optional[str] = None,
user_group_identifier: Optional[str] = None, # user_group_identifier: Optional[str] = None,
start_from: Optional[int] = None, # start_from: Optional[int] = None,
start_to: Optional[int] = None, # start_to: Optional[int] = None,
end_from: Optional[int] = None, # end_from: Optional[int] = None,
end_to: Optional[int] = None, # end_to: Optional[int] = None,
process_status: Optional[str] = None, # process_status: Optional[str] = None,
initiated_by_me: Optional[bool] = None, # initiated_by_me: Optional[bool] = None,
has_terminal_status: Optional[bool] = None, # has_terminal_status: Optional[bool] = None,
has_active_status: Optional[bool] = None, # has_active_status: Optional[bool] = None,
with_tasks_completed_by_me: Optional[bool] = None, # with_tasks_completed_by_me: Optional[bool] = None,
with_tasks_i_can_complete: Optional[bool] = None, # with_tasks_i_can_complete: Optional[bool] = None,
with_tasks_assigned_to_my_group: Optional[bool] = None, # with_tasks_assigned_to_my_group: Optional[bool] = None,
with_relation_to_me: Optional[bool] = None, # with_relation_to_me: Optional[bool] = None,
process_initiator_username: Optional[str] = None, # process_initiator_username: Optional[str] = None,
report_column_list: Optional[list] = None, # report_column_list: Optional[list] = None,
report_filter_by_list: Optional[list] = None, # report_filter_by_list: Optional[list] = None,
oldest_open_human_task_fields: Optional[list] = None, # oldest_open_human_task_fields: Optional[list] = None,
) -> ProcessInstanceReportFilter: # ) -> ProcessInstanceReportFilter:
"""Filter_from_metadata_with_overrides.""" # """Filter_from_metadata_with_overrides."""
report_filter = cls.filter_from_metadata(process_instance_report) # report_filter = cls.filter_from_metadata(process_instance_report)
#
if process_model_identifier is not None: # if process_model_identifier is not None:
report_filter.process_model_identifier = process_model_identifier # report_filter.process_model_identifier = process_model_identifier
if user_group_identifier is not None: # if user_group_identifier is not None:
report_filter.user_group_identifier = user_group_identifier # report_filter.user_group_identifier = user_group_identifier
if start_from is not None: # if start_from is not None:
report_filter.start_from = start_from # report_filter.start_from = start_from
if start_to is not None: # if start_to is not None:
report_filter.start_to = start_to # report_filter.start_to = start_to
if end_from is not None: # if end_from is not None:
report_filter.end_from = end_from # report_filter.end_from = end_from
if end_to is not None: # if end_to is not None:
report_filter.end_to = end_to # report_filter.end_to = end_to
if process_status is not None: # if process_status is not None:
report_filter.process_status = process_status.split(",") # report_filter.process_status = process_status.split(",")
if initiated_by_me is not None: # if initiated_by_me is not None:
report_filter.initiated_by_me = initiated_by_me # report_filter.initiated_by_me = initiated_by_me
if has_terminal_status is not None: # if has_terminal_status is not None:
report_filter.has_terminal_status = has_terminal_status # report_filter.has_terminal_status = has_terminal_status
if has_active_status is not None: # if has_active_status is not None:
report_filter.has_active_status = has_active_status # report_filter.has_active_status = has_active_status
if with_tasks_completed_by_me is not None: # if with_tasks_completed_by_me is not None:
report_filter.with_tasks_completed_by_me = with_tasks_completed_by_me # report_filter.with_tasks_completed_by_me = with_tasks_completed_by_me
if with_tasks_i_can_complete is not None: # if with_tasks_i_can_complete is not None:
report_filter.with_tasks_i_can_complete = with_tasks_i_can_complete # report_filter.with_tasks_i_can_complete = with_tasks_i_can_complete
if process_initiator_username is not None: # if process_initiator_username is not None:
report_filter.process_initiator_username = process_initiator_username # report_filter.process_initiator_username = process_initiator_username
if report_column_list is not None: # if report_column_list is not None:
report_filter.report_column_list = report_column_list # report_filter.report_column_list = report_column_list
if report_filter_by_list is not None: # if report_filter_by_list is not None:
report_filter.report_filter_by_list = report_filter_by_list # report_filter.report_filter_by_list = report_filter_by_list
if oldest_open_human_task_fields is not None: # if oldest_open_human_task_fields is not None:
report_filter.oldest_open_human_task_fields = oldest_open_human_task_fields # report_filter.oldest_open_human_task_fields = oldest_open_human_task_fields
if with_tasks_assigned_to_my_group is not None: # if with_tasks_assigned_to_my_group is not None:
report_filter.with_tasks_assigned_to_my_group = with_tasks_assigned_to_my_group # report_filter.with_tasks_assigned_to_my_group = with_tasks_assigned_to_my_group
if with_relation_to_me is not None: # if with_relation_to_me is not None:
report_filter.with_relation_to_me = with_relation_to_me # report_filter.with_relation_to_me = with_relation_to_me
#
return report_filter # return report_filter
@classmethod @classmethod
def add_metadata_columns_to_process_instance( def add_metadata_columns_to_process_instance(
@ -498,10 +498,16 @@ class ProcessInstanceReportService:
] ]
@classmethod @classmethod
def blah(cls, filters: list[FilterValue], filter_key: str) -> Generator: def get_filter_value(cls, filters: list[FilterValue], filter_key: str) -> Any:
for filter in filters: for filter in filters:
if filter['field_name'] == filter_key and filter['field_value'] is not None: if filter['field_name'] == filter_key and filter['field_value'] is not None:
yield filter['field_value'] return filter['field_value']
@classmethod
def check_filter_value(cls, filters: list[FilterValue], filter_key: str) -> Generator:
value = cls.get_filter_value(filters, filter_key)
if value is not None:
yield value
@classmethod @classmethod
def run_process_instance_report( def run_process_instance_report(
@ -518,7 +524,7 @@ class ProcessInstanceReportService:
process_instance_query = process_instance_query.options(selectinload(ProcessInstanceModel.process_initiator)) process_instance_query = process_instance_query.options(selectinload(ProcessInstanceModel.process_initiator))
filters = report_metadata['filter_by'] filters = report_metadata['filter_by']
for value in cls.blah(filters, 'process_model_identifier'): for value in cls.check_filter_value(filters, 'process_model_identifier'):
process_model = ProcessModelService.get_process_model( process_model = ProcessModelService.get_process_model(
f"{value}", f"{value}",
) )
@ -534,183 +540,194 @@ class ProcessInstanceReportService:
) )
) )
# if report_filter.start_from is not None: for value in cls.check_filter_value(filters, 'start_from'):
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.start_in_seconds >= report_filter.start_from ProcessInstanceModel.start_in_seconds >= value
# ) )
# if report_filter.start_to is not None: for value in cls.check_filter_value(filters, 'start_to'):
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.start_in_seconds <= report_filter.start_to ProcessInstanceModel.start_in_seconds <= value
# ) )
# if report_filter.end_from is not None: for value in cls.check_filter_value(filters, 'end_from'):
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.end_in_seconds >= report_filter.end_from ProcessInstanceModel.end_in_seconds >= value
# ) )
# if report_filter.end_to is not None: for value in cls.check_filter_value(filters, 'end_to'):
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.end_in_seconds <= report_filter.end_to ProcessInstanceModel.end_in_seconds <= value
# ) )
# if report_filter.process_status is not None: for value in cls.check_filter_value(filters, 'process_status'):
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.status.in_(report_filter.process_status) # type: ignore ProcessInstanceModel.status.in_(value.split(',')) # type: ignore
# ) )
#
# if report_filter.initiated_by_me is True: for value in cls.check_filter_value(filters, 'initiated_by_me'):
# process_instance_query = process_instance_query.filter_by(process_initiator=user) if value is True:
# process_instance_query = process_instance_query.filter_by(process_initiator=user)
# if report_filter.has_terminal_status is True:
# process_instance_query = process_instance_query.filter( for value in cls.check_filter_value(filters, 'has_terminal_status'):
# ProcessInstanceModel.status.in_(ProcessInstanceModel.terminal_statuses()) # type: ignore if value is True:
# ) process_instance_query = process_instance_query.filter(
# elif report_filter.has_terminal_status is False: ProcessInstanceModel.status.in_(ProcessInstanceModel.terminal_statuses()) # type: ignore
# process_instance_query = process_instance_query.filter( )
# ProcessInstanceModel.status.not_in(ProcessInstanceModel.terminal_statuses()) # type: ignore elif value is False:
# ) process_instance_query = process_instance_query.filter(
# if report_filter.has_active_status is True: ProcessInstanceModel.status.not_in(ProcessInstanceModel.terminal_statuses()) # type: ignore
# process_instance_query = process_instance_query.filter( )
# ProcessInstanceModel.status.in_(ProcessInstanceModel.active_statuses()) # type: ignore for value in cls.check_filter_value(filters, 'has_active_status'):
# ) if value is True:
# process_instance_query = process_instance_query.filter(
# if report_filter.process_initiator_username is not None: ProcessInstanceModel.status.in_(ProcessInstanceModel.active_statuses()) # type: ignore
# initiator = UserModel.query.filter_by(username=report_filter.process_initiator_username).first() )
# process_initiator_id = -1
# if initiator: for value in cls.check_filter_value(filters, 'process_initiator_username'):
# process_initiator_id = initiator.id initiator = UserModel.query.filter_by(username=value).first()
# process_instance_query = process_instance_query.filter_by(process_initiator_id=process_initiator_id) process_initiator_id = -1
# if initiator:
# if ( process_initiator_id = initiator.id
# not report_filter.with_tasks_completed_by_me process_instance_query = process_instance_query.filter_by(process_initiator_id=process_initiator_id)
# and not report_filter.with_tasks_assigned_to_my_group
# and not report_filter.with_tasks_i_can_complete with_tasks_completed_by_me = cls.get_filter_value(filters, 'with_tasks_completed_by_me')
# and report_filter.with_relation_to_me is True with_tasks_assigned_to_my_group = cls.get_filter_value(filters, 'with_tasks_assigned_to_my_group')
# ): with_tasks_i_can_complete = cls.get_filter_value(filters, 'with_tasks_i_can_complete')
# process_instance_query = process_instance_query.outerjoin(HumanTaskModel).outerjoin( with_relation_to_me = cls.get_filter_value(filters, 'with_relation_to_me')
# HumanTaskUserModel, has_active_status = cls.get_filter_value(filters, 'has_active_status')
# and_( user_group_identifier = cls.get_filter_value(filters, 'user_group_identifier')
# HumanTaskModel.id == HumanTaskUserModel.human_task_id, if (
# HumanTaskUserModel.user_id == user.id, not with_tasks_completed_by_me
# ), and not with_tasks_assigned_to_my_group
# ) and not with_tasks_i_can_complete
# process_instance_query = process_instance_query.filter( and with_relation_to_me is True
# or_( ):
# HumanTaskUserModel.id.is_not(None), process_instance_query = process_instance_query.outerjoin(HumanTaskModel).outerjoin(
# ProcessInstanceModel.process_initiator_id == user.id, HumanTaskUserModel,
# ) and_(
# ) HumanTaskModel.id == HumanTaskUserModel.human_task_id,
# HumanTaskUserModel.user_id == user.id,
# if report_filter.with_tasks_completed_by_me is True: ),
# process_instance_query = process_instance_query.filter( )
# ProcessInstanceModel.process_initiator_id != user.id process_instance_query = process_instance_query.filter(
# ) or_(
# process_instance_query = process_instance_query.join( HumanTaskUserModel.id.is_not(None),
# HumanTaskModel, ProcessInstanceModel.process_initiator_id == user.id,
# and_( )
# HumanTaskModel.process_instance_id == ProcessInstanceModel.id, )
# HumanTaskModel.completed_by_user_id == user.id,
# ), if with_tasks_completed_by_me is True:
# ) process_instance_query = process_instance_query.filter(
# ProcessInstanceModel.process_initiator_id != user.id
# if report_filter.with_tasks_i_can_complete is True: )
# process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.join(
# ProcessInstanceModel.process_initiator_id != user.id HumanTaskModel,
# ) and_(
# process_instance_query = process_instance_query.join( HumanTaskModel.process_instance_id == ProcessInstanceModel.id,
# HumanTaskModel, HumanTaskModel.completed_by_user_id == user.id,
# and_( ),
# HumanTaskModel.process_instance_id == ProcessInstanceModel.id, )
# HumanTaskModel.lane_assignment_id.is_(None), # type: ignore
# ), if with_tasks_i_can_complete is True:
# ).join( process_instance_query = process_instance_query.filter(
# HumanTaskUserModel, ProcessInstanceModel.process_initiator_id != user.id
# and_(HumanTaskUserModel.human_task_id == HumanTaskModel.id, HumanTaskUserModel.user_id == user.id), )
# ) process_instance_query = process_instance_query.join(
# if report_filter.has_active_status: HumanTaskModel,
# process_instance_query = process_instance_query.filter( and_(
# HumanTaskModel.completed.is_(False) # type: ignore HumanTaskModel.process_instance_id == ProcessInstanceModel.id,
# ) HumanTaskModel.lane_assignment_id.is_(None), # type: ignore
# ),
# if report_filter.with_tasks_assigned_to_my_group is True: ).join(
# group_model_join_conditions = [GroupModel.id == HumanTaskModel.lane_assignment_id] HumanTaskUserModel,
# if report_filter.user_group_identifier: and_(HumanTaskUserModel.human_task_id == HumanTaskModel.id, HumanTaskUserModel.user_id == user.id),
# group_model_join_conditions.append(GroupModel.identifier == report_filter.user_group_identifier) )
# if has_active_status:
# process_instance_query = process_instance_query.join(HumanTaskModel) process_instance_query = process_instance_query.filter(
# if report_filter.has_active_status: HumanTaskModel.completed.is_(False) # type: ignore
# process_instance_query = process_instance_query.filter( )
# HumanTaskModel.completed.is_(False) # type: ignore
# ) if with_tasks_assigned_to_my_group is True:
# group_model_join_conditions = [GroupModel.id == HumanTaskModel.lane_assignment_id]
# process_instance_query = process_instance_query.join(GroupModel, and_(*group_model_join_conditions)) if user_group_identifier:
# process_instance_query = process_instance_query.join( group_model_join_conditions.append(GroupModel.identifier == user_group_identifier)
# UserGroupAssignmentModel,
# UserGroupAssignmentModel.group_id == GroupModel.id, process_instance_query = process_instance_query.join(HumanTaskModel)
# ) if has_active_status:
# process_instance_query = process_instance_query.filter(UserGroupAssignmentModel.user_id == user.id) process_instance_query = process_instance_query.filter(
# HumanTaskModel.completed.is_(False) # type: ignore
# instance_metadata_aliases = {} )
# stock_columns = cls.get_column_names_for_model(ProcessInstanceModel)
# if isinstance(report_filter.report_column_list, list): process_instance_query = process_instance_query.join(GroupModel, and_(*group_model_join_conditions))
# process_instance_report.report_metadata["columns"] = report_filter.report_column_list process_instance_query = process_instance_query.join(
# if isinstance(report_filter.report_filter_by_list, list): UserGroupAssignmentModel,
# process_instance_report.report_metadata["filter_by"] = report_filter.report_filter_by_list UserGroupAssignmentModel.group_id == GroupModel.id,
# )
# for column in process_instance_report.report_metadata["columns"]: process_instance_query = process_instance_query.filter(UserGroupAssignmentModel.user_id == user.id)
# if column["accessor"] in stock_columns:
# continue instance_metadata_aliases = {}
# instance_metadata_alias = aliased(ProcessInstanceMetadataModel) report_column_list = cls.get_filter_value(filters, 'report_column_list')
# instance_metadata_aliases[column["accessor"]] = instance_metadata_alias report_filter_by_list = cls.get_filter_value(filters, 'report_filter_by_list')
# stock_columns = cls.get_column_names_for_model(ProcessInstanceModel)
# filter_for_column = None if isinstance(report_column_list, list):
# if "filter_by" in process_instance_report.report_metadata: process_instance_report.report_metadata["columns"] = report_column_list
# filter_for_column = next( if isinstance(report_filter_by_list, list):
# ( process_instance_report.report_metadata["filter_by"] = report_filter_by_list
# f
# for f in process_instance_report.report_metadata["filter_by"] for column in process_instance_report.report_metadata["columns"]:
# if f["field_name"] == column["accessor"] if column["accessor"] in stock_columns:
# ), continue
# None, instance_metadata_alias = aliased(ProcessInstanceMetadataModel)
# ) instance_metadata_aliases[column["accessor"]] = instance_metadata_alias
# isouter = True
# conditions = [ filter_for_column = None
# ProcessInstanceModel.id == instance_metadata_alias.process_instance_id, if "filter_by" in process_instance_report.report_metadata:
# instance_metadata_alias.key == column["accessor"], filter_for_column = next(
# ] (
# if filter_for_column: f
# isouter = False for f in process_instance_report.report_metadata["filter_by"]
# conditions.append(instance_metadata_alias.value == filter_for_column["field_value"]) if f["field_name"] == column["accessor"]
# process_instance_query = process_instance_query.join( ),
# instance_metadata_alias, and_(*conditions), isouter=isouter None,
# ).add_columns(func.max(instance_metadata_alias.value).label(column["accessor"])) )
# isouter = True
# order_by_query_array = [] conditions = [
# order_by_array = process_instance_report.report_metadata["order_by"] ProcessInstanceModel.id == instance_metadata_alias.process_instance_id,
# if len(order_by_array) < 1: instance_metadata_alias.key == column["accessor"],
# order_by_array = ProcessInstanceReportModel.default_order_by() ]
# for order_by_option in order_by_array: if filter_for_column:
# attribute = re.sub("^-", "", order_by_option) isouter = False
# if attribute in stock_columns: conditions.append(instance_metadata_alias.value == filter_for_column["field_value"])
# if order_by_option.startswith("-"): process_instance_query = process_instance_query.join(
# order_by_query_array.append(getattr(ProcessInstanceModel, attribute).desc()) instance_metadata_alias, and_(*conditions), isouter=isouter
# else: ).add_columns(func.max(instance_metadata_alias.value).label(column["accessor"]))
# order_by_query_array.append(getattr(ProcessInstanceModel, attribute).asc())
# elif attribute in instance_metadata_aliases: order_by_query_array = []
# if order_by_option.startswith("-"): order_by_array = process_instance_report.report_metadata["order_by"]
# order_by_query_array.append(func.max(instance_metadata_aliases[attribute].value).desc()) if len(order_by_array) < 1:
# else: order_by_array = ProcessInstanceReportModel.default_order_by()
# order_by_query_array.append(func.max(instance_metadata_aliases[attribute].value).asc()) for order_by_option in order_by_array:
attribute = re.sub("^-", "", order_by_option)
if attribute in stock_columns:
if order_by_option.startswith("-"):
order_by_query_array.append(getattr(ProcessInstanceModel, attribute).desc())
else:
order_by_query_array.append(getattr(ProcessInstanceModel, attribute).asc())
elif attribute in instance_metadata_aliases:
if order_by_option.startswith("-"):
order_by_query_array.append(func.max(instance_metadata_aliases[attribute].value).desc())
else:
order_by_query_array.append(func.max(instance_metadata_aliases[attribute].value).asc())
process_instances = ( process_instances = (
process_instance_query.group_by(ProcessInstanceModel.id) process_instance_query.group_by(ProcessInstanceModel.id)
.add_columns(ProcessInstanceModel.id) .add_columns(ProcessInstanceModel.id)
# .order_by(*order_by_query_array) .order_by(*order_by_query_array)
.paginate(page=page, per_page=per_page, error_out=False) .paginate(page=page, per_page=per_page, error_out=False)
) )
results = cls.add_metadata_columns_to_process_instance( results = cls.add_metadata_columns_to_process_instance(
process_instances.items, process_instance_report.report_metadata["columns"] process_instances.items, process_instance_report.report_metadata["columns"]
) )
# if report_filter.oldest_open_human_task_fields: for value in cls.check_filter_value(filters, 'oldest_open_human_task_fields'):
# results = cls.add_human_task_fields(results, report_filter.oldest_open_human_task_fields) results = cls.add_human_task_fields(results, value)
response_json = { response_json = {
"report": process_instance_report, "report": process_instance_report,
"results": results, "results": results,

View File

@ -37,6 +37,7 @@ import {
convertSecondsToFormattedDateString, convertSecondsToFormattedDateString,
convertSecondsToFormattedDateTime, convertSecondsToFormattedDateTime,
convertSecondsToFormattedTimeHoursMinutes, convertSecondsToFormattedTimeHoursMinutes,
decodeBase64,
encodeBase64, encodeBase64,
getPageInfoFromSearchParams, getPageInfoFromSearchParams,
getProcessModelFullIdentifierFromSearchParams, getProcessModelFullIdentifierFromSearchParams,
@ -287,10 +288,16 @@ export default function ProcessInstanceListTable({
// searchParams.set('key', result.hash); // searchParams.set('key', result.hash);
// setSearchParams(searchParams); // setSearchParams(searchParams);
} }
const stopRefreshing = () => {
// Useful to stop refreshing if an api call gets an error
// since those errors can make the page unusable in any way
const stopRefreshing = (error: any) => {
if (clearRefreshRef.current) { if (clearRefreshRef.current) {
clearRefreshRef.current(); clearRefreshRef.current();
} }
if (error) {
console.error(error);
}
}; };
function getProcessInstances() { function getProcessInstances() {
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
@ -306,10 +313,31 @@ export default function ProcessInstanceListTable({
} }
let queryParamString = `per_page=${perPage}&page=${page}`; let queryParamString = `per_page=${perPage}&page=${page}`;
const userAppliedFilter = searchParams.get('user_filter'); // "columns": [
if (userAppliedFilter) { // {"Header": "id", "accessor": "id"},
queryParamString += `&user_filter=${userAppliedFilter}`; // {
} // "Header": "process_model_display_name",
// "accessor": "process_model_display_name",
// },
// {"Header": "start_in_seconds", "accessor": "start_in_seconds"},
// {"Header": "end_in_seconds", "accessor": "end_in_seconds"},
// {"Header": "status", "accessor": "status"},
// ],
// "filter_by": [
// {"field_name": "initiated_by_me", "field_value": "true"},
// {"field_name": "has_terminal_status", "field_value": "true"},
// ],
// "order_by": ["-start_in_seconds", "-id"],
const postBody: ReportMetadata = {
columns: [],
filter_by: [],
order_by: [],
};
// const userAppliedFilter = searchParams.get('user_filter');
// if (userAppliedFilter) {
// queryParamString += `&user_filter=${userAppliedFilter}`;
// }
if (searchParams.get('report_id')) { if (searchParams.get('report_id')) {
queryParamString += `&report_id=${searchParams.get('report_id')}`; queryParamString += `&report_id=${searchParams.get('report_id')}`;
@ -318,14 +346,29 @@ export default function ProcessInstanceListTable({
} }
if (searchParams.get('report_columns')) { if (searchParams.get('report_columns')) {
queryParamString += `&report_columns=${searchParams.get( // queryParamString += `&report_columns=${searchParams.get(
'report_columns' // 'report_columns'
)}`; // )}`;
// const reportColumnsBase64 = encodeBase64(JSON.stringify(reportColumns()));
const reportColumnsBase64 = searchParams.get('report_columns');
if (reportColumnsBase64) {
const reportColumnsList = JSON.parse(
decodeBase64(reportColumnsBase64)
);
postBody.columns = reportColumnsList;
}
} }
if (searchParams.get('report_filter_by')) { if (searchParams.get('report_filter_by')) {
queryParamString += `&report_filter_by=${searchParams.get( // queryParamString += `&report_filter_by=${searchParams.get(
'report_filter_by' // 'report_filter_by'
)}`; // )}`;
const reportFilterByBase64 = searchParams.get('report_filter_by');
if (reportFilterByBase64) {
const reportFilterByList = JSON.parse(
decodeBase64(reportFilterByBase64)
);
postBody.filter_by = reportFilterByList;
}
} }
Object.keys(dateParametersToAlwaysFilterBy).forEach( Object.keys(dateParametersToAlwaysFilterBy).forEach(
@ -336,7 +379,11 @@ export default function ProcessInstanceListTable({
dateParametersToAlwaysFilterBy[paramName][1]; dateParametersToAlwaysFilterBy[paramName][1];
const searchParamValue = searchParams.get(paramName); const searchParamValue = searchParams.get(paramName);
if (searchParamValue) { if (searchParamValue) {
queryParamString += `&${paramName}=${searchParamValue}`; // queryParamString += `&${paramName}=${searchParamValue}`;
postBody.filter_by.push({
field_name: paramName,
field_value: searchParamValue,
});
const dateString = convertSecondsToFormattedDateString( const dateString = convertSecondsToFormattedDateString(
searchParamValue as any searchParamValue as any
); );
@ -356,11 +403,19 @@ export default function ProcessInstanceListTable({
paramName === 'process_model_identifier' && paramName === 'process_model_identifier' &&
processModelFullIdentifier processModelFullIdentifier
) { ) {
queryParamString += `&process_model_identifier=${processModelFullIdentifier}`; // queryParamString += `&process_model_identifier=${processModelFullIdentifier}`;
postBody.filter_by.push({
field_name: 'process_model_identifier',
field_value: processModelFullIdentifier,
});
} else if (searchParams.get(paramName)) { } else if (searchParams.get(paramName)) {
// @ts-expect-error TS(7053) FIXME: // @ts-expect-error TS(7053) FIXME:
const functionToCall = parametersToGetFromSearchParams[paramName]; const functionToCall = parametersToGetFromSearchParams[paramName];
queryParamString += `&${paramName}=${searchParams.get(paramName)}`; // queryParamString += `&${paramName}=${searchParams.get(paramName)}`;
postBody.filter_by.push({
field_name: paramName,
field_value: searchParams.get(paramName),
});
if (functionToCall !== null) { if (functionToCall !== null) {
functionToCall(searchParams.get(paramName) || ''); functionToCall(searchParams.get(paramName) || '');
} }
@ -377,8 +432,19 @@ export default function ProcessInstanceListTable({
path: `${processInstanceApiSearchPath}?${queryParamString}`, path: `${processInstanceApiSearchPath}?${queryParamString}`,
successCallback: setProcessInstancesFromResult, successCallback: setProcessInstancesFromResult,
httpMethod: 'POST', httpMethod: 'POST',
failureCallback: stopRefreshing,
onUnauthorized: stopRefreshing, onUnauthorized: stopRefreshing,
postBody: {'report_metadata': {'filter_by': [{'field_name': 'process_model_identifier', 'field_value': 'example/with-milestones' }]}}, postBody: {
report_metadata: postBody,
// report_metadata: {
// filter_by: [
// {
// field_name: 'process_model_identifier',
// field_value: 'example/with-milestones',
// },
// ],
// },
},
}); });
} }
function processResultForProcessModels(result: any) { function processResultForProcessModels(result: any) {
@ -618,7 +684,8 @@ export default function ProcessInstanceListTable({
undefined, undefined,
paginationQueryParamPrefix paginationQueryParamPrefix
); );
let queryParamString = `per_page=${perPage}&page=${page}&user_filter=true`; // let queryParamString = `per_page=${perPage}&page=${page}&user_filter=true`;
let queryParamString = `per_page=${perPage}&page=${page}`;
const { const {
valid, valid,
startFromSeconds, startFromSeconds,
@ -631,6 +698,24 @@ export default function ProcessInstanceListTable({
return; return;
} }
// "columns": [
// {"Header": "id", "accessor": "id"},
// {
// "Header": "process_model_display_name",
// "accessor": "process_model_display_name",
// },
// {"Header": "start_in_seconds", "accessor": "start_in_seconds"},
// {"Header": "end_in_seconds", "accessor": "end_in_seconds"},
// {"Header": "status", "accessor": "status"},
// ],
// "filter_by": [
// {"field_name": "initiated_by_me", "field_value": "true"},
// {"field_name": "has_terminal_status", "field_value": "true"},
// ],
// "order_by": ["-start_in_seconds", "-id"],
// const postBody = {};
if (startFromSeconds) { if (startFromSeconds) {
queryParamString += `&start_from=${startFromSeconds}`; queryParamString += `&start_from=${startFromSeconds}`;
} }
@ -947,7 +1032,8 @@ export default function ProcessInstanceListTable({
reportColumnForEditing.accessor reportColumnForEditing.accessor
); );
if (reportFilter) { if (reportFilter) {
reportColumnForEditing.filter_field_value = reportFilter.field_value; reportColumnForEditing.filter_field_value =
reportFilter.field_value || '';
reportColumnForEditing.filter_operator = reportColumnForEditing.filter_operator =
reportFilter.operator || 'equals'; reportFilter.operator || 'equals';
} }

View File

@ -163,7 +163,7 @@ export interface MessageInstance {
export interface ReportFilter { export interface ReportFilter {
field_name: string; field_name: string;
field_value: string; field_value: string | null;
operator?: string; operator?: string;
} }