Enhance documentation and workflow management in EspoCRM
- Update README.md to include a table of contents and detailed sections on workflow management and custom scripts. - Remove deprecated 'runWorkflow' field from CVmhErstgespraech localization files. - Add 'runWorkflow' field to detail layout for CVmhErstgespraech. - Update workflow_manager.php to improve workflow listing and management functionality. - Adjust cache timestamps in config.php. - Create CUSTOM_DIRECTORY.md to outline the custom directory structure and best practices. - Add README.md for workflow definitions with usage examples and JSON format specifications. - Introduce new workflow definitions for 'vmh-erstberatung-abschließen' and its backup.
This commit is contained in:
189
README.md
189
README.md
@@ -1,8 +1,26 @@
|
|||||||
KI-basierte Bearbeitung von EspoCRM: Struktur und Funktionsweise
|
KI-basierte Bearbeitung von EspoCRM: Struktur und Funktionsweise
|
||||||
|
|
||||||
|
## Inhaltsverzeichnis
|
||||||
|
1. [Überblick](#überblick)
|
||||||
|
2. [Relevante Dateipfade und Verzeichnisstruktur](#1-relevante-dateipfade-und-verzeichnisstruktur)
|
||||||
|
3. [Workflow-Verwaltung](#workflow-verwaltung)
|
||||||
|
4. [Auslösen von Änderungen und Rebuild-Prozess](#auslösen-von-änderungen-und-rebuild-prozess)
|
||||||
|
|
||||||
|
## Überblick
|
||||||
|
|
||||||
Unter der Annahme, dass die KI direkten Zugriff auf das Dateisystem des EspoCRM-Servers hat (z. B. via SSH, API-Integration oder lokales Scripting), kann sie EspoCRM modifizieren, indem sie JSON-basierte Metadata-Dateien bearbeitet. EspoCRM ist modular aufgebaut und speichert Konfigurationen für Entitäten, Felder, Beziehungen, Views und Layouts in diesen Dateien. Änderungen erfolgen idealerweise im custom/-Verzeichnis, um Core-Dateien nicht zu überschreiben und Upgrades zu erleichtern. Die KI würde Dateien lesen, parsen (z. B. als JSON), modifizieren und speichern – gefolgt von einem Rebuild-Prozess, um die Änderungen anzuwenden.
|
Unter der Annahme, dass die KI direkten Zugriff auf das Dateisystem des EspoCRM-Servers hat (z. B. via SSH, API-Integration oder lokales Scripting), kann sie EspoCRM modifizieren, indem sie JSON-basierte Metadata-Dateien bearbeitet. EspoCRM ist modular aufgebaut und speichert Konfigurationen für Entitäten, Felder, Beziehungen, Views und Layouts in diesen Dateien. Änderungen erfolgen idealerweise im custom/-Verzeichnis, um Core-Dateien nicht zu überschreiben und Upgrades zu erleichtern. Die KI würde Dateien lesen, parsen (z. B. als JSON), modifizieren und speichern – gefolgt von einem Rebuild-Prozess, um die Änderungen anzuwenden.
|
||||||
|
|
||||||
EspoCRM basiert auf PHP (Backend) und Backbone.js (Frontend), mit einer rekursiven Merging-Mechanik: Custom-Dateien überschreiben oder erweitern Core-Definitionen. Keine integrierte KI-Schnittstelle existiert, aber mit Dateizugriff kann die KI automatisierte Anpassungen vornehmen, z. B. Felder hinzufügen, Views anpassen oder Beziehungen definieren. Nachfolgend detaillierte Infos basierend auf der offiziellen Dokumentation und Community-Beiträgen.
|
EspoCRM basiert auf PHP (Backend) und Backbone.js (Frontend), mit einer rekursiven Merging-Mechanik: Custom-Dateien überschreiben oder erweitern Core-Definitionen. Keine integrierte KI-Schnittstelle existiert, aber mit Dateizugriff kann die KI automatisierte Anpassungen vornehmen, z. B. Felder hinzufügen, Views anpassen oder Beziehungen definieren. Nachfolgend detaillierte Infos basierend auf der offiziellen Dokumentation und Community-Beiträgen.
|
||||||
|
|
||||||
|
### Custom Scripts & Tools
|
||||||
|
|
||||||
|
**Workflow-Verwaltung:**
|
||||||
|
- `custom/scripts/workflow_manager.php` - Zentrale Schnittstelle für Workflow-Verwaltung (Import/Export/List/Delete)
|
||||||
|
- `custom/scripts/check_and_rebuild.sh` - Validierungs- und Rebuild-Script
|
||||||
|
|
||||||
|
**Workflow-Definitionen:**
|
||||||
|
- `custom/workflows/*.json` - Versionierte Workflow-Definitionen (Simple & BPM)
|
||||||
|
- `custom/workflows/README.md` - Workflow-Format-Dokumentation
|
||||||
1. Relevante Dateipfade und Verzeichnisstruktur
|
1. Relevante Dateipfade und Verzeichnisstruktur
|
||||||
|
|
||||||
Alle relevanten Dateien liegen im JSON-Format und werden in einer hierarchischen Struktur organisiert. Die KI sollte immer im custom/Espo/Custom/Resources/metadata/-Ordner arbeiten, da Änderungen hier persistent sind und nicht bei Updates verloren gehen. Core-Dateien (z. B. unter application/Espo/Resources/metadata/) dienen als Referenz, aber sollten nicht modifiziert werden.
|
Alle relevanten Dateien liegen im JSON-Format und werden in einer hierarchischen Struktur organisiert. Die KI sollte immer im custom/Espo/Custom/Resources/metadata/-Ordner arbeiten, da Änderungen hier persistent sind und nicht bei Updates verloren gehen. Core-Dateien (z. B. unter application/Espo/Resources/metadata/) dienen als Referenz, aber sollten nicht modifiziert werden.
|
||||||
@@ -148,6 +166,177 @@ JSON
|
|||||||
Datenbank-Effekte: Neue Felder/Links in entityDefs erzeugen Tabellen/Spalten (bei Rebuild).
|
Datenbank-Effekte: Neue Felder/Links in entityDefs erzeugen Tabellen/Spalten (bei Rebuild).
|
||||||
Frontend-Effekte: clientDefs/Layouts ändern UI sofort nach Rebuild (z. B. neue Panels, Views).
|
Frontend-Effekte: clientDefs/Layouts ändern UI sofort nach Rebuild (z. B. neue Panels, Views).
|
||||||
Fehlerquellen: Ungültiges JSON oder falsche Typen können zu Fehlern führen (z. B. fehlende required-Felder).
|
Fehlerquellen: Ungültiges JSON oder falsche Typen können zu Fehlern führen (z. B. fehlende required-Felder).
|
||||||
|
|
||||||
|
## Workflow-Verwaltung
|
||||||
|
|
||||||
|
EspoCRM bietet zwei Arten von Workflows für Automatisierung:
|
||||||
|
|
||||||
|
### Simple Workflows (Regel-basiert)
|
||||||
|
- Trigger-basierte Workflows für einfache Automationen
|
||||||
|
- **Trigger-Typen:**
|
||||||
|
- `afterRecordSaved` - Nach Erstellen oder Aktualisieren
|
||||||
|
- `afterRecordCreated` - Nur nach Erstellen
|
||||||
|
- `afterRecordUpdated` - Nur nach Aktualisieren
|
||||||
|
- `manual` - Manuell ausgeführt
|
||||||
|
- `scheduled` - Zeitgesteuert
|
||||||
|
- **Bedingungen:**
|
||||||
|
- Vergleiche: `equals`, `notEquals`, `greaterThan`, `lessThan`, `contains`, `isEmpty`
|
||||||
|
- Änderungen: `changed`, `notChanged`, `wasEqual`
|
||||||
|
- **Aktionen:**
|
||||||
|
- `sendEmail` - E-Mail versenden
|
||||||
|
- `createEntity` - Record erstellen
|
||||||
|
- `updateEntity` - Record aktualisieren
|
||||||
|
- `relateTo` / `unrelateFrom` - Verknüpfungen
|
||||||
|
- `createNotification` - Benachrichtigung
|
||||||
|
|
||||||
|
### BPM Flowcharts (Komplex)
|
||||||
|
- Visuelle Workflows mit BPMN 2.0-Standard
|
||||||
|
- Start-Events: Signal, Conditional, Timer
|
||||||
|
- Gateways (Exclusive, Inclusive, Parallel), Tasks, End-Events
|
||||||
|
- Für komplexe, mehrstufige Geschäftsprozesse
|
||||||
|
|
||||||
|
### Workflow-Dateien
|
||||||
|
Workflow-Definitionen werden im Ordner `custom/workflows/` als JSON abgelegt:
|
||||||
|
- **`custom/workflows/*.json`** - Workflow-Definitionen (Simple oder BPM)
|
||||||
|
- **`custom/workflows/README.md`** - Dokumentation zu Formaten und Verwendung
|
||||||
|
|
||||||
|
### Workflow Manager Script
|
||||||
|
**Zentrale Schnittstelle:** `custom/scripts/workflow_manager.php`
|
||||||
|
|
||||||
|
Dieses Script ermöglicht die Verwaltung aller Workflows (Simple und BPM) über die Kommandozeile:
|
||||||
|
|
||||||
|
#### Verfügbare Aktionen
|
||||||
|
|
||||||
|
**1. Alle Workflows auflisten**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php list
|
||||||
|
```
|
||||||
|
Zeigt beide Workflow-Typen (BPM Flowcharts und Simple Workflows) mit Status, ID, Name und Entity.
|
||||||
|
|
||||||
|
**2. Workflow-Details anzeigen**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php read <workflow-id>
|
||||||
|
```
|
||||||
|
Gibt alle Details eines Workflows als JSON aus.
|
||||||
|
|
||||||
|
**3. Workflow importieren**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php import /var/www/html/custom/workflows/workflow.json
|
||||||
|
```
|
||||||
|
Importiert einen Workflow aus einer JSON-Datei. Unterstützt sowohl Simple Workflows als auch BPM Flowcharts. Erstellt automatisch eine neue ID.
|
||||||
|
|
||||||
|
**4. Workflow exportieren**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php export <workflow-id> /var/www/html/custom/workflows/exported.json
|
||||||
|
```
|
||||||
|
Exportiert einen Workflow in eine JSON-Datei für Backup oder Migration.
|
||||||
|
|
||||||
|
**5. Workflow löschen**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php delete <workflow-id>
|
||||||
|
```
|
||||||
|
Löscht einen Workflow (mit Bestätigung). Funktioniert für beide Workflow-Typen.
|
||||||
|
|
||||||
|
### JSON-Formate
|
||||||
|
|
||||||
|
#### Simple Workflow Format
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "simple",
|
||||||
|
"name": "workflow-name",
|
||||||
|
"entity_type": "EntityName",
|
||||||
|
"trigger_type": "afterRecordSaved",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Beschreibung der Funktion",
|
||||||
|
"conditions_all": [
|
||||||
|
{
|
||||||
|
"comparison": "equals",
|
||||||
|
"fieldToCompare": "fieldName",
|
||||||
|
"value": "expectedValue",
|
||||||
|
"subjectType": "value"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions_any": [],
|
||||||
|
"conditions_formula": null,
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"type": "sendEmail",
|
||||||
|
"from": "specifiedEmailAddress",
|
||||||
|
"fromEmailAddress": "sender@example.com",
|
||||||
|
"to": "targetEntity",
|
||||||
|
"emailTemplateId": null,
|
||||||
|
"doNotStore": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtige Felder:**
|
||||||
|
- `comparison` - Vergleichsoperator (siehe Bedingungen oben)
|
||||||
|
- `fieldToCompare` - Feldname für Bedingung
|
||||||
|
- `subjectType` - Typ des Vergleichswerts (`value`, `field`, etc.)
|
||||||
|
- `from` / `to` - E-Mail-Empfänger (`targetEntity`, `specifiedEmailAddress`, `system`)
|
||||||
|
|
||||||
|
#### BPM Flowchart Format
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "bpm",
|
||||||
|
"name": "flowchart-name",
|
||||||
|
"target_type": "EntityName",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Beschreibung",
|
||||||
|
"data": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"type": "eventStartSignal",
|
||||||
|
"id": "start1",
|
||||||
|
"signalName": "@signalName"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"elements_data_hash": {},
|
||||||
|
"event_start_all_id_list": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
1. **Versionierung:** Workflows als JSON-Dateien im `custom/workflows/` Verzeichnis versionieren
|
||||||
|
2. **Naming Convention:** Beschreibende Namen mit Präfix (z.B. `vmh-erstberatung-abschliessen.json`)
|
||||||
|
3. **Testen:** Nach Import immer über Admin-Interface testen
|
||||||
|
4. **Backup:** Regelmäßig Export für wichtige Workflows durchführen
|
||||||
|
5. **Dokumentation:** Description-Feld aussagekräftig füllen
|
||||||
|
|
||||||
|
### Beispiel-Workflows
|
||||||
|
|
||||||
|
**`custom/workflows/vmh-erstberatung-abschliessen.json`**
|
||||||
|
- Sendet E-Mail bei Status-Wechsel zu "Warte auf Mandatierung"
|
||||||
|
- Trigger: afterRecordSaved
|
||||||
|
- Bedingungen: Status = "Warte auf Mandatierung" UND Status hat sich geändert
|
||||||
|
- Aktion: E-Mail an targetEntity senden
|
||||||
|
|
||||||
|
**Anwendungsbeispiel:**
|
||||||
|
```bash
|
||||||
|
# Alle Workflows exportieren (Backup)
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php list | grep ID | \
|
||||||
|
awk '{print $3}' | while read id; do
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php export "${id%,}" \
|
||||||
|
"/var/www/html/custom/workflows/backup-${id%,}.json"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Workflow aus Datei (re-)importieren
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php import \
|
||||||
|
/var/www/html/custom/workflows/vmh-erstberatung-abschliessen.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Workflow-Entwicklung mit KI
|
||||||
|
|
||||||
|
Für KI-gestützte Workflow-Erstellung:
|
||||||
|
1. Workflow-Definition im `custom/workflows/` Verzeichnis als JSON ablegen
|
||||||
|
2. Mit `import` Befehl in EspoCRM einspielen
|
||||||
|
3. Im Admin-Interface testen und bei Bedarf anpassen
|
||||||
|
4. Mit `export` Befehl aktualisierten Workflow sichern
|
||||||
|
5. JSON-Datei im Repository committen
|
||||||
Rebuild auslösen:
|
Rebuild auslösen:
|
||||||
Manuell: Administration > Clear Cache & Rebuild (löscht Caches und merged Metadata neu).
|
Manuell: Administration > Clear Cache & Rebuild (löscht Caches und merged Metadata neu).
|
||||||
Programmatisch (für KI): Die KI kann den Cache-Ordner löschen (data/cache/) oder ein PHP-Skript ausführen, das den Rebuild triggert (z. B. via EspoCRMs CLI: php command.php Rebuild). Keine direkte API, aber machbar mit Dateizugriff (z. B. exec("php rebuild.php")).
|
Programmatisch (für KI): Die KI kann den Cache-Ordner löschen (data/cache/) oder ein PHP-Skript ausführen, das den Rebuild triggert (z. B. via EspoCRMs CLI: php command.php Rebuild). Keine direkte API, aber machbar mit Dateizugriff (z. B. exec("php rebuild.php")).
|
||||||
|
|||||||
122
custom/CUSTOM_DIRECTORY.md
Normal file
122
custom/CUSTOM_DIRECTORY.md
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
# EspoCRM Custom Directory - Übersicht
|
||||||
|
|
||||||
|
## Verzeichnisstruktur
|
||||||
|
|
||||||
|
```
|
||||||
|
custom/
|
||||||
|
├── Espo/
|
||||||
|
│ ├── Custom/ # Custom Entitäten, Services, Controller etc.
|
||||||
|
│ └── Modules/ # Custom Module
|
||||||
|
├── scripts/ # Custom PHP Scripts für Wartung/Verwaltung
|
||||||
|
│ ├── check_and_rebuild.sh
|
||||||
|
│ └── workflow_manager.php
|
||||||
|
└── workflows/ # Workflow-Definitionen als JSON
|
||||||
|
├── README.md
|
||||||
|
├── vmh-erstberatung-abschliessen.json
|
||||||
|
└── vmh-erstberatung-abschliessen-backup.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Zweck der Verzeichnisse
|
||||||
|
|
||||||
|
### custom/Espo/Custom/
|
||||||
|
Hauptverzeichnis für EspoCRM-Customizations:
|
||||||
|
- `Resources/metadata/` - Entity-, Field-, Client-Definitionen
|
||||||
|
- `Resources/layouts/` - UI-Layout-Definitionen
|
||||||
|
- `Resources/i18n/` - Übersetzungen
|
||||||
|
- `Classes/` - Custom PHP-Klassen
|
||||||
|
- `Controllers/` - Custom Controller
|
||||||
|
- `Services/` - Custom Services
|
||||||
|
- `Repositories/` - Custom Repositories
|
||||||
|
|
||||||
|
### custom/Espo/Modules/
|
||||||
|
Zusätzliche Module (z.B. von Extensions):
|
||||||
|
- Jedes Modul hat eigene `Resources/metadata/` Struktur
|
||||||
|
- Module sind gekapselt und wiederverwendbar
|
||||||
|
|
||||||
|
### custom/scripts/
|
||||||
|
**PHP Scripts für Wartung und Verwaltung:**
|
||||||
|
|
||||||
|
#### workflow_manager.php
|
||||||
|
Zentrale Schnittstelle für Workflow-Verwaltung:
|
||||||
|
- **list** - Alle Workflows (BPM + Simple) auflisten
|
||||||
|
- **read** - Workflow-Details anzeigen
|
||||||
|
- **import** - Workflow aus JSON importieren
|
||||||
|
- **export** - Workflow nach JSON exportieren
|
||||||
|
- **delete** - Workflow löschen
|
||||||
|
|
||||||
|
**Verwendung:**
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php <action> [args]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### check_and_rebuild.sh
|
||||||
|
Validierung und Rebuild:
|
||||||
|
- JSON-Syntax-Prüfung
|
||||||
|
- EspoCRM Rebuild
|
||||||
|
- Cache-Bereinigung
|
||||||
|
|
||||||
|
### custom/workflows/
|
||||||
|
**Workflow-Definitionen als JSON:**
|
||||||
|
- Versionskontrolle für Workflows
|
||||||
|
- Import/Export über workflow_manager.php
|
||||||
|
- Sowohl Simple Workflows als auch BPM Flowcharts
|
||||||
|
- Format-Dokumentation in `README.md`
|
||||||
|
|
||||||
|
**Workflow-Typen:**
|
||||||
|
1. **Simple Workflows** - Regel-basierte Automationen
|
||||||
|
- Trigger: afterRecordSaved, afterRecordCreated, scheduled, manual
|
||||||
|
- Bedingungen: Feld-Vergleiche (equals, changed, contains, etc.)
|
||||||
|
- Aktionen: sendEmail, createEntity, updateEntity, etc.
|
||||||
|
|
||||||
|
2. **BPM Flowcharts** - Komplexe BPMN 2.0-Workflows
|
||||||
|
- Visuelle Designer im Admin-Interface
|
||||||
|
- Start-Events, Gateways, Tasks, End-Events
|
||||||
|
- Für mehrstufige Geschäftsprozesse
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Workflow-Entwicklung
|
||||||
|
1. Workflow als JSON in `custom/workflows/` erstellen
|
||||||
|
2. Mit `workflow_manager.php import` einspielen
|
||||||
|
3. Im Admin-Interface testen
|
||||||
|
4. Bei Änderungen: Export → Anpassung → Import
|
||||||
|
|
||||||
|
### Versionskontrolle
|
||||||
|
- Alle JSON-Dateien in Git committen
|
||||||
|
- Beschreibende Dateinamen (z.B. `vmh-<entity>-<funktion>.json`)
|
||||||
|
- Regelmäßig Backups per `export` erstellen
|
||||||
|
|
||||||
|
### Änderungen anwenden
|
||||||
|
Nach Metadata-Änderungen immer:
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/command.php rebuild
|
||||||
|
# oder
|
||||||
|
./custom/scripts/check_and_rebuild.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nützliche Befehle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Alle Workflows auflisten
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php list
|
||||||
|
|
||||||
|
# Workflow importieren
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php import \
|
||||||
|
/var/www/html/custom/workflows/my-workflow.json
|
||||||
|
|
||||||
|
# Workflow exportieren (Backup)
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php export \
|
||||||
|
<workflow-id> /var/www/html/custom/workflows/backup-workflow.json
|
||||||
|
|
||||||
|
# System rebuilden
|
||||||
|
docker exec espocrm php /var/www/html/command.php rebuild
|
||||||
|
|
||||||
|
# Cache löschen
|
||||||
|
docker exec espocrm rm -rf /var/www/html/data/cache/*
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dokumentation
|
||||||
|
|
||||||
|
- **Hauptdokumentation:** `/README.md` - Vollständige KI-Dokumentation für EspoCRM
|
||||||
|
- **Workflow-Formate:** `/custom/workflows/README.md` - JSON-Format-Spezifikationen
|
||||||
|
- **EspoCRM Docs:** https://docs.espocrm.com
|
||||||
@@ -59,7 +59,6 @@
|
|||||||
"beendigungstatbestand": "Beendigungstatbestand",
|
"beendigungstatbestand": "Beendigungstatbestand",
|
||||||
"contact": "Kontakt",
|
"contact": "Kontakt",
|
||||||
"nchsterAnruf": "Nächster Anruf",
|
"nchsterAnruf": "Nächster Anruf",
|
||||||
"runWorkflow": "Workflow ausführen",
|
|
||||||
"dokumentesvmherstgespraech": "Dokumente"
|
"dokumentesvmherstgespraech": "Dokumente"
|
||||||
},
|
},
|
||||||
"links": {
|
"links": {
|
||||||
|
|||||||
@@ -60,7 +60,6 @@
|
|||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
"nchsterAnruf": "Next Call",
|
"nchsterAnruf": "Next Call",
|
||||||
"dokumentesvmherstgespraech": "Documents",
|
"dokumentesvmherstgespraech": "Documents",
|
||||||
"runWorkflow": "Run Workflow",
|
|
||||||
"testArray": "Test Array"
|
"testArray": "Test Array"
|
||||||
},
|
},
|
||||||
"links": {
|
"links": {
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"name": "runWorkflow"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": ":assignedUser"
|
"name": ":assignedUser"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nchsterAnruf"
|
"name": "nchsterAnruf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "runWorkflow"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -204,7 +204,7 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"optionsReference": "CVmhMietverhltnis.kndigungsgrundWohnraum",
|
"optionsReference": "CVmhMietverhltnis.kndigungsgrundWohnraum",
|
||||||
"default": "Mietrückstand",
|
"default": "Mietrückstand",
|
||||||
"style": {},
|
"style": [],
|
||||||
"maxLength": 100,
|
"maxLength": 100,
|
||||||
"isCustom": true
|
"isCustom": true
|
||||||
},
|
},
|
||||||
@@ -416,21 +416,6 @@
|
|||||||
"minuteStep": 5,
|
"minuteStep": 5,
|
||||||
"tooltip": true,
|
"tooltip": true,
|
||||||
"isCustom": true
|
"isCustom": true
|
||||||
},
|
|
||||||
"runWorkflow": {
|
|
||||||
"type": "link-button",
|
|
||||||
"mode": "runEspoWorkflow",
|
|
||||||
"popupHeight": 800,
|
|
||||||
"popupWidth": 600,
|
|
||||||
"style": "primary",
|
|
||||||
"buttonSize": "btn-md",
|
|
||||||
"confirmationDialog": true,
|
|
||||||
"confirmationText": "Soll der Vorgang abgeschlossen und die Ersteinschätzung versandt werden?",
|
|
||||||
"title": "runWorkflow Title",
|
|
||||||
"isCustom": true,
|
|
||||||
"default": null,
|
|
||||||
"buttonLabel": "Erstberatung versenden",
|
|
||||||
"readOnly": true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"links": {
|
"links": {
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Workflow Manager Script for EspoCRM
|
* Workflow Manager Script for EspoCRM
|
||||||
|
*
|
||||||
|
* Manages both BPM Flowcharts and Simple Workflows
|
||||||
|
*
|
||||||
* Usage: php workflow_manager.php <action> [options]
|
* Usage: php workflow_manager.php <action> [options]
|
||||||
* Actions: list, read <id>, delete <id>, edit <id> <json_data>, execute <id> <record_id>, test <id>
|
*
|
||||||
|
* Actions:
|
||||||
|
* list - List all workflows (BPM and Simple)
|
||||||
|
* read <id> - Read workflow details
|
||||||
|
* delete <id> - Delete a workflow
|
||||||
|
* import <file> - Import workflow from JSON file
|
||||||
|
* export <id> <file> - Export workflow to JSON file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$config = require '/var/www/html/data/config-internal.php';
|
$config = require '/var/www/html/data/config-internal.php';
|
||||||
@@ -22,69 +31,196 @@ function connectDB() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listWorkflows($pdo) {
|
function listWorkflows($pdo) {
|
||||||
$stmt = $pdo->query("SELECT id, name FROM bpmn_flowchart WHERE deleted = 0");
|
echo "=== BPM Flowcharts ===\n";
|
||||||
|
$stmt = $pdo->query("SELECT id, name, target_type, is_active FROM bpmn_flowchart WHERE deleted = 0");
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
echo "Verfügbare Workflows:\n";
|
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
echo "- ID: {$row['id']}, Name: {$row['name']}\n";
|
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
||||||
|
echo " {$active} ID: {$row['id']}, Name: {$row['name']}, Entity: {$row['target_type']}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "\n=== Simple Workflows ===\n";
|
||||||
|
$stmt = $pdo->query("SELECT id, name, entity_type, type, is_active FROM workflow WHERE deleted = 0");
|
||||||
|
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
foreach ($results as $row) {
|
||||||
|
$active = $row['is_active'] ? '[AKTIV]' : '[INAKTIV]';
|
||||||
|
$name = $row['name'] ?: '(unnamed)';
|
||||||
|
echo " {$active} ID: {$row['id']}, Name: {$name}, Entity: {$row['entity_type']}, Type: {$row['type']}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readWorkflow($pdo, $id) {
|
function readWorkflow($pdo, $id) {
|
||||||
|
// Try BPM first
|
||||||
$stmt = $pdo->prepare("SELECT * FROM bpmn_flowchart WHERE id = ? AND deleted = 0");
|
$stmt = $pdo->prepare("SELECT * FROM bpmn_flowchart WHERE id = ? AND deleted = 0");
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if ($row) {
|
if ($row) {
|
||||||
echo "Workflow Details:\n";
|
echo "=== BPM Flowchart ===\n";
|
||||||
echo json_encode($row, JSON_PRETTY_PRINT) . "\n";
|
echo json_encode($row, JSON_PRETTY_PRINT) . "\n";
|
||||||
} else {
|
return;
|
||||||
echo "Workflow nicht gefunden.\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try Simple Workflow
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM workflow WHERE id = ? AND deleted = 0");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($row) {
|
||||||
|
echo "=== Simple Workflow ===\n";
|
||||||
|
echo json_encode($row, JSON_PRETTY_PRINT) . "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Workflow nicht gefunden.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteWorkflow($pdo, $id) {
|
function deleteWorkflow($pdo, $id) {
|
||||||
echo "Bist du sicher, dass du den Workflow $id löschen möchtest? (ja/nein): ";
|
echo "Bist du sicher, dass du den Workflow $id löschen möchtest? (ja/nein): ";
|
||||||
$input = trim(fgets(STDIN));
|
$input = trim(fgets(STDIN));
|
||||||
if (strtolower($input) === 'ja') {
|
if (strtolower($input) !== 'ja') {
|
||||||
$stmt = $pdo->prepare("UPDATE bpmn_flowchart SET deleted = 1 WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
echo "Workflow gelöscht.\n";
|
|
||||||
} else {
|
|
||||||
echo "Abgebrochen.\n";
|
echo "Abgebrochen.\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try BPM first
|
||||||
|
$stmt = $pdo->prepare("UPDATE bpmn_flowchart SET deleted = 1 WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
echo "BPM Flowchart gelöscht.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try Simple Workflow
|
||||||
|
$stmt = $pdo->prepare("UPDATE workflow SET deleted = 1 WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
echo "Simple Workflow gelöscht.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Workflow nicht gefunden.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
function editWorkflow($pdo, $id, $jsonData) {
|
function importWorkflow($pdo, $file) {
|
||||||
$data = json_decode($jsonData, true);
|
if (!file_exists($file)) {
|
||||||
|
die("Datei nicht gefunden: $file\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$json = file_get_contents($file);
|
||||||
|
$data = json_decode($json, true);
|
||||||
|
|
||||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
die("Ungültiges JSON.\n");
|
die("Ungültiges JSON in Datei.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$type = $data['type'] ?? 'unknown';
|
||||||
|
$now = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
if ($type === 'simple') {
|
||||||
|
// Import Simple Workflow
|
||||||
|
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO workflow (
|
||||||
|
id, name, entity_type, type, is_active, is_internal,
|
||||||
|
description, conditions_all, conditions_any, conditions_formula,
|
||||||
|
actions, portal_only, scheduling, scheduling_apply_timezone,
|
||||||
|
process_order, created_at, modified_at, deleted
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)
|
||||||
|
");
|
||||||
|
$stmt->execute([
|
||||||
|
$id,
|
||||||
|
$data['name'],
|
||||||
|
$data['entity_type'],
|
||||||
|
$data['trigger_type'],
|
||||||
|
$data['is_active'] ?? 1,
|
||||||
|
0,
|
||||||
|
$data['description'] ?? null,
|
||||||
|
json_encode($data['conditions_all'] ?? []),
|
||||||
|
json_encode($data['conditions_any'] ?? []),
|
||||||
|
$data['conditions_formula'] ?? null,
|
||||||
|
json_encode($data['actions'] ?? []),
|
||||||
|
0,
|
||||||
|
'0 0 * * *',
|
||||||
|
1,
|
||||||
|
10,
|
||||||
|
$now,
|
||||||
|
$now
|
||||||
|
]);
|
||||||
|
echo "✓ Simple Workflow importiert: $id - {$data['name']}\n";
|
||||||
|
} elseif ($type === 'bpm') {
|
||||||
|
// Import BPM Flowchart
|
||||||
|
$id = substr(bin2hex(random_bytes(12)), 0, 17);
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO bpmn_flowchart (
|
||||||
|
id, name, target_type, is_active,
|
||||||
|
created_at, modified_at, data, elements_data_hash,
|
||||||
|
deleted, has_none_start_event, event_start_id_list, event_start_all_id_list
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 0, '[]', ?)
|
||||||
|
");
|
||||||
|
$stmt->execute([
|
||||||
|
$id,
|
||||||
|
$data['name'],
|
||||||
|
$data['target_type'],
|
||||||
|
$data['is_active'] ?? 1,
|
||||||
|
$now,
|
||||||
|
$now,
|
||||||
|
json_encode($data['data']),
|
||||||
|
json_encode($data['elements_data_hash']),
|
||||||
|
json_encode($data['event_start_all_id_list'] ?? [])
|
||||||
|
]);
|
||||||
|
echo "✓ BPM Flowchart importiert: $id - {$data['name']}\n";
|
||||||
|
} else {
|
||||||
|
die("Unbekannter Workflow-Typ: $type\n");
|
||||||
}
|
}
|
||||||
$stmt = $pdo->prepare("UPDATE bpmn_flowchart SET data = ?, modified_at = NOW() WHERE id = ?");
|
|
||||||
$stmt->execute([json_encode($data), $id]);
|
|
||||||
echo "Workflow aktualisiert.\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeWorkflow($pdo, $id, $recordId) {
|
function exportWorkflow($pdo, $id, $file) {
|
||||||
// Einfache Simulation: Setze Status oder triggere Event
|
// Try BPM first
|
||||||
// In Realität würde man EspoCRM-API verwenden
|
$stmt = $pdo->prepare("SELECT * FROM bpmn_flowchart WHERE id = ? AND deleted = 0");
|
||||||
echo "Workflow $id für Record $recordId ausführen...\n";
|
|
||||||
// Beispiel: Status setzen
|
|
||||||
$stmt = $pdo->prepare("UPDATE c_vmh_erstgespraech SET status = 'Warte auf Mandatierung' WHERE id = ?");
|
|
||||||
$stmt->execute([$recordId]);
|
|
||||||
echo "Status gesetzt. Workflow sollte ausgelöst werden.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function testWorkflow($pdo, $id) {
|
|
||||||
// Simuliere Bedingungen
|
|
||||||
$stmt = $pdo->prepare("SELECT data FROM bpmn_flowchart WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
$stmt->execute([$id]);
|
||||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if ($row) {
|
if ($row) {
|
||||||
$data = json_decode($row['data'], true);
|
$export = [
|
||||||
echo "Teste Workflow: " . (isset($data['list'][0]['text']) ? $data['list'][0]['text'] : 'Unbekannt') . "\n";
|
'type' => 'bpm',
|
||||||
// Prüfe Bedingungen (vereinfacht)
|
'name' => $row['name'],
|
||||||
echo "Bedingungen: " . json_encode(isset($data['list'][0]['conditionsAll']) ? $data['list'][0]['conditionsAll'] : []) . "\n";
|
'target_type' => $row['target_type'],
|
||||||
|
'is_active' => (bool)$row['is_active'],
|
||||||
|
'description' => $row['description'],
|
||||||
|
'data' => json_decode($row['data'], true),
|
||||||
|
'elements_data_hash' => json_decode($row['elements_data_hash'], true),
|
||||||
|
'event_start_all_id_list' => json_decode($row['event_start_all_id_list'], true)
|
||||||
|
];
|
||||||
|
file_put_contents($file, json_encode($export, JSON_PRETTY_PRINT));
|
||||||
|
echo "✓ BPM Flowchart exportiert nach: $file\n";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try Simple Workflow
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM workflow WHERE id = ? AND deleted = 0");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($row) {
|
||||||
|
$export = [
|
||||||
|
'type' => 'simple',
|
||||||
|
'name' => $row['name'],
|
||||||
|
'entity_type' => $row['entity_type'],
|
||||||
|
'trigger_type' => $row['type'],
|
||||||
|
'is_active' => (bool)$row['is_active'],
|
||||||
|
'description' => $row['description'],
|
||||||
|
'conditions_all' => json_decode($row['conditions_all'], true),
|
||||||
|
'conditions_any' => json_decode($row['conditions_any'], true),
|
||||||
|
'conditions_formula' => $row['conditions_formula'],
|
||||||
|
'actions' => json_decode($row['actions'], true)
|
||||||
|
];
|
||||||
|
file_put_contents($file, json_encode($export, JSON_PRETTY_PRINT));
|
||||||
|
echo "✓ Simple Workflow exportiert nach: $file\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Workflow nicht gefunden.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdo = connectDB();
|
$pdo = connectDB();
|
||||||
@@ -102,19 +238,16 @@ switch ($action) {
|
|||||||
if (!isset($argv[2])) die("Usage: delete <id>\n");
|
if (!isset($argv[2])) die("Usage: delete <id>\n");
|
||||||
deleteWorkflow($pdo, $argv[2]);
|
deleteWorkflow($pdo, $argv[2]);
|
||||||
break;
|
break;
|
||||||
case 'edit':
|
case 'import':
|
||||||
if (!isset($argv[2]) || !isset($argv[3])) die("Usage: edit <id> <json_data>\n");
|
if (!isset($argv[2])) die("Usage: import <file>\n");
|
||||||
editWorkflow($pdo, $argv[2], $argv[3]);
|
importWorkflow($pdo, $argv[2]);
|
||||||
break;
|
break;
|
||||||
case 'execute':
|
case 'export':
|
||||||
if (!isset($argv[2]) || !isset($argv[3])) die("Usage: execute <workflow_id> <record_id>\n");
|
if (!isset($argv[2]) || !isset($argv[3])) die("Usage: export <id> <file>\n");
|
||||||
executeWorkflow($pdo, $argv[2], $argv[3]);
|
exportWorkflow($pdo, $argv[2], $argv[3]);
|
||||||
break;
|
|
||||||
case 'test':
|
|
||||||
if (!isset($argv[2])) die("Usage: test <id>\n");
|
|
||||||
testWorkflow($pdo, $argv[2]);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
echo "Unbekannte Aktion. Verfügbare: list, read, delete, edit, execute, test\n";
|
echo "Unbekannte Aktion.\n";
|
||||||
|
echo "Verfügbare Aktionen: list, read, delete, import, export\n";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
70
custom/workflows/README.md
Normal file
70
custom/workflows/README.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Workflow Definitions
|
||||||
|
|
||||||
|
This directory contains workflow definitions in JSON format that can be imported into EspoCRM using the workflow manager script.
|
||||||
|
|
||||||
|
## File Format
|
||||||
|
|
||||||
|
### Simple Workflow
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "simple",
|
||||||
|
"name": "workflow-name",
|
||||||
|
"entity_type": "EntityName",
|
||||||
|
"trigger_type": "afterRecordSaved",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Description of what this workflow does",
|
||||||
|
"conditions_all": [],
|
||||||
|
"conditions_any": [],
|
||||||
|
"conditions_formula": null,
|
||||||
|
"actions": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Trigger Types:**
|
||||||
|
- `afterRecordSaved` - After record is created or updated
|
||||||
|
- `afterRecordCreated` - Only after record is created
|
||||||
|
- `scheduled` - Runs on a schedule
|
||||||
|
|
||||||
|
**Condition Types:**
|
||||||
|
- `equals`, `notEquals`, `greaterThan`, `lessThan`, `contains`, `notContains`, `isEmpty`, `isNotEmpty`, `isTrue`, `isFalse`, `wasEqual`, `wasNotEqual`, `changed`, `notChanged`
|
||||||
|
|
||||||
|
**Action Types:**
|
||||||
|
- `sendEmail` - Send email to recipient
|
||||||
|
- `createEntity` - Create a new record
|
||||||
|
- `updateEntity` - Update current record
|
||||||
|
- `relateTo` - Link to another record
|
||||||
|
- `unrelateFrom` - Unlink from record
|
||||||
|
- `applyAssignmentRule` - Apply assignment rules
|
||||||
|
- `createNotification` - Create notification
|
||||||
|
|
||||||
|
### BPM Flowchart
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "bpm",
|
||||||
|
"name": "flowchart-name",
|
||||||
|
"target_type": "EntityName",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Description",
|
||||||
|
"data": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"elements_data_hash": {},
|
||||||
|
"event_start_all_id_list": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Import a workflow:
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php import /var/www/html/custom/workflows/your-workflow.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Export a workflow:
|
||||||
|
```bash
|
||||||
|
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php export <workflow-id> /var/www/html/custom/workflows/exported.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
- `vmh-erstberatung-abschliessen.json` - Sends email and sets status when consultation is completed
|
||||||
43
custom/workflows/vmh-erstberatung-abschliessen-backup.json
Normal file
43
custom/workflows/vmh-erstberatung-abschliessen-backup.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"type": "simple",
|
||||||
|
"name": "vmh-erstberatung-abschlie\u00dfen",
|
||||||
|
"entity_type": "CVmhErstgespraech",
|
||||||
|
"trigger_type": "afterRecordSaved",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Versendet Erstberatungs-E-Mail und setzt Status auf \"Warte auf Mandatierung\"",
|
||||||
|
"conditions_all": [
|
||||||
|
{
|
||||||
|
"comparison": "equals",
|
||||||
|
"subjectType": "value",
|
||||||
|
"cid": 0,
|
||||||
|
"fieldToCompare": "status",
|
||||||
|
"type": "all",
|
||||||
|
"value": "Warte auf Mandatierung"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comparison": "changed",
|
||||||
|
"subjectType": null,
|
||||||
|
"cid": 1,
|
||||||
|
"fieldToCompare": "status",
|
||||||
|
"type": "all"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions_any": [],
|
||||||
|
"conditions_formula": null,
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"type": "sendEmail",
|
||||||
|
"cid": 0,
|
||||||
|
"id": "423a120400",
|
||||||
|
"from": "specifiedEmailAddress",
|
||||||
|
"fromEmailAddress": "anwalt@vermieterhelden.de",
|
||||||
|
"to": "targetEntity",
|
||||||
|
"toEmailAddress": null,
|
||||||
|
"replyTo": null,
|
||||||
|
"emailTemplateId": null,
|
||||||
|
"emailTemplateName": null,
|
||||||
|
"doNotStore": false,
|
||||||
|
"optOutLink": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
27
custom/workflows/vmh-erstberatung-abschliessen.json
Normal file
27
custom/workflows/vmh-erstberatung-abschliessen.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"type": "simple",
|
||||||
|
"name": "vmh-erstberatung-abschließen",
|
||||||
|
"entity_type": "CVmhErstgespraech",
|
||||||
|
"trigger_type": "afterRecordSaved",
|
||||||
|
"is_active": true,
|
||||||
|
"description": "Sendet E-Mail und setzt Status wenn Erstberatung abgeschlossen wird",
|
||||||
|
"conditions_all": [
|
||||||
|
{
|
||||||
|
"type": "equals",
|
||||||
|
"attribute": "status",
|
||||||
|
"value": "Warte auf Mandatierung"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions_any": [],
|
||||||
|
"conditions_formula": null,
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"type": "sendEmail",
|
||||||
|
"from": "system",
|
||||||
|
"to": "contactId",
|
||||||
|
"emailTemplateId": null,
|
||||||
|
"subject": "Erstberatung abgeschlossen",
|
||||||
|
"body": "Ihre Erstberatung wurde erfolgreich abgeschlossen. Wir warten nun auf Ihre Mandatierung."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -348,8 +348,8 @@ return [
|
|||||||
0 => 'youtube.com',
|
0 => 'youtube.com',
|
||||||
1 => 'google.com'
|
1 => 'google.com'
|
||||||
],
|
],
|
||||||
'cacheTimestamp' => 1768945598,
|
'cacheTimestamp' => 1768949725,
|
||||||
'microtime' => 1768945598.792157,
|
'microtime' => 1768949725.049459,
|
||||||
'siteUrl' => 'https://crm.bitbylaw.com',
|
'siteUrl' => 'https://crm.bitbylaw.com',
|
||||||
'fullTextSearchMinLength' => 4,
|
'fullTextSearchMinLength' => 4,
|
||||||
'appTimestamp' => 1768843902,
|
'appTimestamp' => 1768843902,
|
||||||
|
|||||||
Reference in New Issue
Block a user