331 lines
16 KiB
Python
331 lines
16 KiB
Python
# Copyright (c) 2025 Patrick Motsch
|
|
# All rights reserved.
|
|
|
|
import logging
|
|
from typing import Dict, Any
|
|
from modules.workflows.methods.methodBase import MethodBase
|
|
from modules.datamodels.datamodelWorkflowActions import WorkflowActionDefinition, WorkflowActionParameter
|
|
from modules.shared.frontendTypes import FrontendType
|
|
|
|
# Import helpers
|
|
from .helpers.adfConverter import AdfConverterHelper
|
|
from .helpers.documentParsing import DocumentParsingHelper
|
|
|
|
# Import actions
|
|
from .actions.connectJira import connectJira
|
|
from .actions.exportTicketsAsJson import exportTicketsAsJson
|
|
from .actions.importTicketsFromJson import importTicketsFromJson
|
|
from .actions.mergeTicketData import mergeTicketData
|
|
from .actions.parseCsvContent import parseCsvContent
|
|
from .actions.parseExcelContent import parseExcelContent
|
|
from .actions.createCsvContent import createCsvContent
|
|
from .actions.createExcelContent import createExcelContent
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class MethodJira(MethodBase):
|
|
"""JIRA operations methods."""
|
|
|
|
def __init__(self, services):
|
|
super().__init__(services)
|
|
self.name = "jira"
|
|
self.description = "JIRA operations methods"
|
|
# Store connections in memory (keyed by connectionId)
|
|
self._connections: Dict[str, Any] = {}
|
|
|
|
# Initialize helper modules
|
|
self.adfConverter = AdfConverterHelper(self)
|
|
self.documentParsing = DocumentParsingHelper(self)
|
|
|
|
# RBAC-Integration: Action-Definitionen mit actionId
|
|
self._actions = {
|
|
"connectJira": WorkflowActionDefinition(
|
|
actionId="jira.connectJira",
|
|
description="Connect to JIRA instance and create ticket interface",
|
|
outputType="ActionResult",
|
|
parameters={
|
|
"apiUsername": WorkflowActionParameter(
|
|
name="apiUsername",
|
|
type="str",
|
|
frontendType=FrontendType.EMAIL,
|
|
required=True,
|
|
description="JIRA API username/email"
|
|
),
|
|
"apiTokenConfigKey": WorkflowActionParameter(
|
|
name="apiTokenConfigKey",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="APP_CONFIG key name for JIRA API token"
|
|
),
|
|
"apiUrl": WorkflowActionParameter(
|
|
name="apiUrl",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="JIRA instance URL (e.g., https://example.atlassian.net)"
|
|
),
|
|
"projectCode": WorkflowActionParameter(
|
|
name="projectCode",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="JIRA project code (e.g., DCS)"
|
|
),
|
|
"issueType": WorkflowActionParameter(
|
|
name="issueType",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="JIRA issue type (e.g., Task)"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
uiHint="textarea",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=True,
|
|
description="Field mapping definition as JSON string or dict"
|
|
)
|
|
},
|
|
execute=connectJira.__get__(self, self.__class__)
|
|
),
|
|
"exportTicketsAsJson": WorkflowActionDefinition(
|
|
actionId="jira.exportTicketsAsJson",
|
|
description="Export tickets from JIRA as JSON list",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"connectionId": WorkflowActionParameter(
|
|
name="connectionId",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Connection ID from connectJira action result"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=False,
|
|
description="Field mapping definition (if not provided, uses stored definition)"
|
|
)
|
|
},
|
|
execute=exportTicketsAsJson.__get__(self, self.__class__)
|
|
),
|
|
"importTicketsFromJson": WorkflowActionDefinition(
|
|
actionId="jira.importTicketsFromJson",
|
|
description="Import ticket data from JSON back to JIRA",
|
|
outputType="ActionResult",
|
|
parameters={
|
|
"connectionId": WorkflowActionParameter(
|
|
name="connectionId",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=True,
|
|
description="Connection ID from connectJira action result"
|
|
),
|
|
"ticketData": WorkflowActionParameter(
|
|
name="ticketData",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing ticket data as JSON"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=False,
|
|
description="Field mapping definition (if not provided, uses stored definition)"
|
|
)
|
|
},
|
|
execute=importTicketsFromJson.__get__(self, self.__class__)
|
|
),
|
|
"mergeTicketData": WorkflowActionDefinition(
|
|
actionId="jira.mergeTicketData",
|
|
description="Merge JIRA export data with existing SharePoint data",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"jiraData": WorkflowActionParameter(
|
|
name="jiraData",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing JIRA ticket data as JSON array"
|
|
),
|
|
"existingData": WorkflowActionParameter(
|
|
name="existingData",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing existing SharePoint data as JSON array"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=True,
|
|
description="Field mapping definition"
|
|
),
|
|
"idField": WorkflowActionParameter(
|
|
name="idField",
|
|
type="str",
|
|
frontendType=FrontendType.TEXT,
|
|
required=False,
|
|
default="ID",
|
|
description="Field name to use as ID for merging"
|
|
)
|
|
},
|
|
execute=mergeTicketData.__get__(self, self.__class__)
|
|
),
|
|
"parseCsvContent": WorkflowActionDefinition(
|
|
actionId="jira.parseCsvContent",
|
|
description="Parse CSV content with custom headers",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"csvContent": WorkflowActionParameter(
|
|
name="csvContent",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing CSV file content as bytes"
|
|
),
|
|
"skipRows": WorkflowActionParameter(
|
|
name="skipRows",
|
|
type="int",
|
|
frontendType=FrontendType.NUMBER,
|
|
required=False,
|
|
default=2,
|
|
description="Number of header rows to skip",
|
|
validation={"min": 0, "max": 100}
|
|
),
|
|
"hasCustomHeaders": WorkflowActionParameter(
|
|
name="hasCustomHeaders",
|
|
type="bool",
|
|
frontendType=FrontendType.CHECKBOX,
|
|
required=False,
|
|
default=True,
|
|
description="Whether CSV has custom header rows"
|
|
)
|
|
},
|
|
execute=parseCsvContent.__get__(self, self.__class__)
|
|
),
|
|
"parseExcelContent": WorkflowActionDefinition(
|
|
actionId="jira.parseExcelContent",
|
|
description="Parse Excel content with custom headers",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"excelContent": WorkflowActionParameter(
|
|
name="excelContent",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing Excel file content as bytes"
|
|
),
|
|
"skipRows": WorkflowActionParameter(
|
|
name="skipRows",
|
|
type="int",
|
|
frontendType=FrontendType.NUMBER,
|
|
required=False,
|
|
default=3,
|
|
description="Number of header rows to skip",
|
|
validation={"min": 0, "max": 100}
|
|
),
|
|
"hasCustomHeaders": WorkflowActionParameter(
|
|
name="hasCustomHeaders",
|
|
type="bool",
|
|
frontendType=FrontendType.CHECKBOX,
|
|
required=False,
|
|
default=True,
|
|
description="Whether Excel has custom header rows"
|
|
)
|
|
},
|
|
execute=parseExcelContent.__get__(self, self.__class__)
|
|
),
|
|
"createCsvContent": WorkflowActionDefinition(
|
|
actionId="jira.createCsvContent",
|
|
description="Create CSV content with custom headers",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"data": WorkflowActionParameter(
|
|
name="data",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing data as JSON (with data field from mergeTicketData)"
|
|
),
|
|
"headers": WorkflowActionParameter(
|
|
name="headers",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=False,
|
|
description="Document reference containing headers JSON (from parseCsvContent/parseExcelContent)"
|
|
),
|
|
"columns": WorkflowActionParameter(
|
|
name="columns",
|
|
type="List[str]",
|
|
frontendType=FrontendType.MULTISELECT,
|
|
required=False,
|
|
description="List of column names (if not provided, extracted from taskSyncDefinition or data)"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=False,
|
|
description="Field mapping definition (used to extract column names if columns not provided)"
|
|
)
|
|
},
|
|
execute=createCsvContent.__get__(self, self.__class__)
|
|
),
|
|
"createExcelContent": WorkflowActionDefinition(
|
|
actionId="jira.createExcelContent",
|
|
description="Create Excel content with custom headers",
|
|
outputType="DocumentList",
|
|
parameters={
|
|
"data": WorkflowActionParameter(
|
|
name="data",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=True,
|
|
description="Document reference containing data as JSON (with data field from mergeTicketData)"
|
|
),
|
|
"headers": WorkflowActionParameter(
|
|
name="headers",
|
|
type="DocumentList",
|
|
frontendType=FrontendType.DOCUMENT_REFERENCE,
|
|
required=False,
|
|
description="Document reference containing headers JSON (from parseExcelContent)"
|
|
),
|
|
"columns": WorkflowActionParameter(
|
|
name="columns",
|
|
type="List[str]",
|
|
frontendType=FrontendType.MULTISELECT,
|
|
required=False,
|
|
description="List of column names (if not provided, extracted from taskSyncDefinition or data)"
|
|
),
|
|
"taskSyncDefinition": WorkflowActionParameter(
|
|
name="taskSyncDefinition",
|
|
type="str",
|
|
frontendType=FrontendType.TEXTAREA,
|
|
required=False,
|
|
description="Field mapping definition (used to extract column names if columns not provided)"
|
|
)
|
|
},
|
|
execute=createExcelContent.__get__(self, self.__class__)
|
|
)
|
|
}
|
|
|
|
# Validate actions after definition
|
|
self._validateActions()
|
|
|
|
# Register actions as methods (optional, für direkten Zugriff)
|
|
self.connectJira = connectJira.__get__(self, self.__class__)
|
|
self.exportTicketsAsJson = exportTicketsAsJson.__get__(self, self.__class__)
|
|
self.importTicketsFromJson = importTicketsFromJson.__get__(self, self.__class__)
|
|
self.mergeTicketData = mergeTicketData.__get__(self, self.__class__)
|
|
self.parseCsvContent = parseCsvContent.__get__(self, self.__class__)
|
|
self.parseExcelContent = parseExcelContent.__get__(self, self.__class__)
|
|
self.createCsvContent = createCsvContent.__get__(self, self.__class__)
|
|
self.createExcelContent = createExcelContent.__get__(self, self.__class__)
|
|
|