Enhance workflow manager and definitions with category support for better organization
This commit is contained in:
10
README.md
10
README.md
@@ -203,7 +203,13 @@ Workflow-Definitionen werden im Ordner `custom/workflows/` als JSON abgelegt:
|
|||||||
### Workflow Manager Script
|
### Workflow Manager Script
|
||||||
**Zentrale Schnittstelle:** `custom/scripts/workflow_manager.php`
|
**Zentrale Schnittstelle:** `custom/scripts/workflow_manager.php`
|
||||||
|
|
||||||
Dieses Script ermöglicht die Verwaltung aller Workflows (Simple und BPM) über die Kommandozeile:
|
Dieses Script ermöglicht die Verwaltung aller Workflows (Simple und BPM) über die Kommandozeile.
|
||||||
|
|
||||||
|
**Unterstützte Funktionen:**
|
||||||
|
- ✓ Kategorisierung von Workflows
|
||||||
|
- ✓ Import/Export mit Kategorie-Namen
|
||||||
|
- ✓ Übersichtliche Darstellung nach Kategorien
|
||||||
|
- ✓ Unterstützung für beide Workflow-Typen (Simple & BPM)
|
||||||
|
|
||||||
#### Verfügbare Aktionen
|
#### Verfügbare Aktionen
|
||||||
|
|
||||||
@@ -248,6 +254,7 @@ Löscht einen Workflow (mit Bestätigung). Funktioniert für beide Workflow-Type
|
|||||||
"trigger_type": "afterRecordSaved",
|
"trigger_type": "afterRecordSaved",
|
||||||
"is_active": true,
|
"is_active": true,
|
||||||
"description": "Beschreibung der Funktion",
|
"description": "Beschreibung der Funktion",
|
||||||
|
"category": "Kategorie-Name",
|
||||||
"conditions_all": [
|
"conditions_all": [
|
||||||
{
|
{
|
||||||
"comparison": "equals",
|
"comparison": "equals",
|
||||||
@@ -272,6 +279,7 @@ Löscht einen Workflow (mit Bestätigung). Funktioniert für beide Workflow-Type
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Wichtige Felder:**
|
**Wichtige Felder:**
|
||||||
|
- `category` - **NEU:** Name der Workflow-Kategorie (optional, für bessere Organisation)
|
||||||
- `comparison` - Vergleichsoperator (siehe Bedingungen oben)
|
- `comparison` - Vergleichsoperator (siehe Bedingungen oben)
|
||||||
- `fieldToCompare` - Feldname für Bedingung
|
- `fieldToCompare` - Feldname für Bedingung
|
||||||
- `subjectType` - Typ des Vergleichswerts (`value`, `field`, etc.)
|
- `subjectType` - Typ des Vergleichswerts (`value`, `field`, etc.)
|
||||||
|
|||||||
@@ -31,8 +31,15 @@ function connectDB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listWorkflows($pdo) {
|
function listWorkflows($pdo) {
|
||||||
|
// Load categories
|
||||||
|
$categories = [];
|
||||||
|
$stmt = $pdo->query("SELECT id, name FROM workflow_category WHERE deleted = 0 ORDER BY `order`, name");
|
||||||
|
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $cat) {
|
||||||
|
$categories[$cat['id']] = $cat['name'];
|
||||||
|
}
|
||||||
|
|
||||||
echo "=== BPM Flowcharts ===\n";
|
echo "=== BPM Flowcharts ===\n";
|
||||||
$stmt = $pdo->query("SELECT id, name, target_type, is_active FROM bpmn_flowchart WHERE deleted = 0");
|
$stmt = $pdo->query("SELECT id, name, target_type, is_active FROM bpmn_flowchart WHERE deleted = 0 ORDER BY name");
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
||||||
@@ -40,12 +47,21 @@ function listWorkflows($pdo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
echo "\n=== Simple Workflows ===\n";
|
echo "\n=== Simple Workflows ===\n";
|
||||||
$stmt = $pdo->query("SELECT id, name, entity_type, type, is_active FROM workflow WHERE deleted = 0");
|
$stmt = $pdo->query("SELECT id, name, entity_type, type, is_active, category_id FROM workflow WHERE deleted = 0 ORDER BY category_id, name");
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$currentCategory = null;
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
|
$catId = $row['category_id'];
|
||||||
|
if ($catId !== $currentCategory) {
|
||||||
|
$currentCategory = $catId;
|
||||||
|
$catName = $catId && isset($categories[$catId]) ? $categories[$catId] : 'Ohne Kategorie';
|
||||||
|
echo "\n [Kategorie: {$catName}]\n";
|
||||||
|
}
|
||||||
|
|
||||||
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
||||||
$name = $row['name'] ?: '(unnamed)';
|
$name = $row['name'] ?: '(unnamed)';
|
||||||
echo " {$active} ID: {$row['id']}, Name: {$name}, Entity: {$row['entity_type']}, Type: {$row['type']}\n";
|
echo " {$active} ID: {$row['id']}, Name: {$name}, Entity: {$row['entity_type']}, Type: {$row['type']}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,13 +136,23 @@ function importWorkflow($pdo, $file) {
|
|||||||
if ($type === 'simple') {
|
if ($type === 'simple') {
|
||||||
// Import Simple Workflow
|
// Import Simple Workflow
|
||||||
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
||||||
|
|
||||||
|
// Resolve category by name if provided
|
||||||
|
$categoryId = null;
|
||||||
|
if (isset($data['category'])) {
|
||||||
|
$stmt = $pdo->prepare("SELECT id FROM workflow_category WHERE name = ? AND deleted = 0");
|
||||||
|
$stmt->execute([$data['category']]);
|
||||||
|
$cat = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$categoryId = $cat ? $cat['id'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
INSERT INTO workflow (
|
INSERT INTO workflow (
|
||||||
id, name, entity_type, type, is_active, is_internal,
|
id, name, entity_type, type, is_active, is_internal,
|
||||||
description, conditions_all, conditions_any, conditions_formula,
|
description, conditions_all, conditions_any, conditions_formula,
|
||||||
actions, portal_only, scheduling, scheduling_apply_timezone,
|
actions, portal_only, scheduling, scheduling_apply_timezone,
|
||||||
process_order, created_at, modified_at, deleted
|
process_order, category_id, created_at, modified_at, deleted
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
||||||
");
|
");
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$id,
|
$id,
|
||||||
@@ -144,10 +170,12 @@ function importWorkflow($pdo, $file) {
|
|||||||
'0 0 * * *',
|
'0 0 * * *',
|
||||||
1,
|
1,
|
||||||
10,
|
10,
|
||||||
|
$categoryId,
|
||||||
$now,
|
$now,
|
||||||
$now
|
$now
|
||||||
]);
|
]);
|
||||||
echo "✓ Simple Workflow importiert: $id - {$data['name']}\n";
|
$catInfo = $categoryId ? " (Kategorie: {$data['category']})" : "";
|
||||||
|
echo "✓ Simple Workflow importiert: $id - {$data['name']}{$catInfo}\n";
|
||||||
} elseif ($type === 'bpm') {
|
} elseif ($type === 'bpm') {
|
||||||
// Import BPM Flowchart
|
// Import BPM Flowchart
|
||||||
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
||||||
@@ -198,7 +226,7 @@ function exportWorkflow($pdo, $id, $file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try Simple Workflow
|
// Try Simple Workflow
|
||||||
$stmt = $pdo->prepare("SELECT * FROM workflow WHERE id = ? AND deleted = 0");
|
$stmt = $pdo->prepare("SELECT w.*, wc.name as category_name FROM workflow w LEFT JOIN workflow_category wc ON w.category_id = wc.id WHERE w.id = ? AND w.deleted = 0");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
@@ -215,6 +243,12 @@ function exportWorkflow($pdo, $id, $file) {
|
|||||||
'conditions_formula' => $row['conditions_formula'],
|
'conditions_formula' => $row['conditions_formula'],
|
||||||
'actions' => json_decode($row['actions'], true)
|
'actions' => json_decode($row['actions'], true)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Add category name if exists
|
||||||
|
if ($row['category_name']) {
|
||||||
|
$export['category'] = $row['category_name'];
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents($file, json_encode($export, JSON_PRETTY_PRINT));
|
file_put_contents($file, json_encode($export, JSON_PRETTY_PRINT));
|
||||||
echo "✓ Simple Workflow exportiert nach: $file\n";
|
echo "✓ Simple Workflow exportiert nach: $file\n";
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ This directory contains workflow definitions in JSON format that can be imported
|
|||||||
"trigger_type": "afterRecordSaved",
|
"trigger_type": "afterRecordSaved",
|
||||||
"is_active": true,
|
"is_active": true,
|
||||||
"description": "Description of what this workflow does",
|
"description": "Description of what this workflow does",
|
||||||
|
"category": "Category Name",
|
||||||
"conditions_all": [],
|
"conditions_all": [],
|
||||||
"conditions_any": [],
|
"conditions_any": [],
|
||||||
"conditions_formula": null,
|
"conditions_formula": null,
|
||||||
@@ -24,6 +25,7 @@ This directory contains workflow definitions in JSON format that can be imported
|
|||||||
- `afterRecordSaved` - After record is created or updated
|
- `afterRecordSaved` - After record is created or updated
|
||||||
- `afterRecordCreated` - Only after record is created
|
- `afterRecordCreated` - Only after record is created
|
||||||
- `scheduled` - Runs on a schedule
|
- `scheduled` - Runs on a schedule
|
||||||
|
- `manual` - Manually triggered
|
||||||
|
|
||||||
**Condition Types:**
|
**Condition Types:**
|
||||||
- `equals`, `notEquals`, `greaterThan`, `lessThan`, `contains`, `notContains`, `isEmpty`, `isNotEmpty`, `isTrue`, `isFalse`, `wasEqual`, `wasNotEqual`, `changed`, `notChanged`
|
- `equals`, `notEquals`, `greaterThan`, `lessThan`, `contains`, `notContains`, `isEmpty`, `isNotEmpty`, `isTrue`, `isFalse`, `wasEqual`, `wasNotEqual`, `changed`, `notChanged`
|
||||||
|
|||||||
Reference in New Issue
Block a user