Update EspoCRM Custom Directory documentation and modify cache timestamps in config
- Enhanced the EspoCRM Custom Directory documentation to provide a comprehensive overview of the directory structure and customization options. - Updated cache timestamps in the configuration file to reflect recent changes.
This commit is contained in:
794
README.md
794
README.md
@@ -2,53 +2,131 @@ KI-basierte Bearbeitung von EspoCRM: Struktur und Funktionsweise
|
|||||||
|
|
||||||
## Inhaltsverzeichnis
|
## Inhaltsverzeichnis
|
||||||
1. [Überblick](#überblick)
|
1. [Überblick](#überblick)
|
||||||
2. [Relevante Dateipfade und Verzeichnisstruktur](#1-relevante-dateipfade-und-verzeichnisstruktur)
|
2. [Custom Directory Struktur](#custom-directory-struktur)
|
||||||
3. [Workflow-Verwaltung](#workflow-verwaltung)
|
3. [Rebuild-Prozess](#rebuild-prozess)
|
||||||
4. [Auslösen von Änderungen und Rebuild-Prozess](#auslösen-von-änderungen-und-rebuild-prozess)
|
4. [Dateiformate und JSON-Strukturen](#dateiformate-und-json-strukturen)
|
||||||
|
5. [Workflow-Verwaltung](#workflow-verwaltung)
|
||||||
|
6. [Internationalisierung (i18n) und Tooltips](#internationalisierung-i18n-und-tooltips)
|
||||||
|
7. [Formula-Scripts und Custom PHP-Erweiterungen](#formula-scripts-und-custom-php-erweiterungen)
|
||||||
|
8. [Panel-Labels und Übersetzungen](#panel-labels-und-übersetzungen)
|
||||||
|
9. [Custom JavaScript & CSS Integration](#custom-javascript--css-integration)
|
||||||
|
10. [Reports und Report-Panels](#reports-und-report-panels)
|
||||||
|
11. [Portal-Freigabe-System](#portal-freigabe-system)
|
||||||
|
12. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
## Überblick
|
## Ü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.
|
EspoCRM ist ein modular aufgebautes CRM-System, das auf PHP (Backend) und Backbone.js (Frontend) basiert. Konfigurationen für Entitäten, Felder, Beziehungen, Views und Layouts werden in JSON-basierten Metadata-Dateien gespeichert.
|
||||||
|
|
||||||
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.
|
Die Anpassung erfolgt über das **custom/**-Verzeichnis, um Core-Dateien nicht zu überschreiben und Upgrades zu erleichtern. EspoCRM verwendet eine rekursive Merging-Mechanik: Custom-Dateien überschreiben oder erweitern Core-Definitionen.
|
||||||
|
|
||||||
### Custom Scripts & Tools
|
**Anpassungsprozess:**
|
||||||
|
1. JSON-Dateien im `custom/`-Verzeichnis erstellen/bearbeiten
|
||||||
|
2. Rebuild-Script ausführen (validiert, merged, aktualisiert DB)
|
||||||
|
3. Änderungen sind sofort wirksam
|
||||||
|
|
||||||
**Workflow-Verwaltung:**
|
Keine integrierte KI-Schnittstelle existiert, aber mit Dateizugriff können automatisierte Anpassungen vorgenommen werden: Felder hinzufügen, Views anpassen, Beziehungen definieren, Workflows erstellen.
|
||||||
- `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 Directory Struktur
|
||||||
- `custom/workflows/*.json` - Versionierte Workflow-Definitionen (Simple & BPM)
|
|
||||||
- `custom/workflows/README.md` - Workflow-Format-Dokumentation
|
|
||||||
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.
|
**Vollständige Übersicht:** Siehe `/custom/CUSTOM_DIRECTORY.md` für detaillierte Dokumentation aller Custom-Verzeichnisse.
|
||||||
|
|
||||||
Hauptverzeichnis für Customizations: custom/Espo/Custom/Resources/
|
**Wichtigste Bereiche:**
|
||||||
Unterordner: metadata/ (für Definitionsdateien wie entityDefs, clientDefs).
|
- `custom/Espo/Custom/Resources/metadata/` - Backend-Definitionen (entityDefs, clientDefs, etc.)
|
||||||
Weitere Unterordner: layouts/ (für UI-Layouts), i18n/ (für Übersetzungen, falls relevant).
|
- `custom/Espo/Custom/Classes/` - Custom PHP-Klassen (Formula-Funktionen, Services)
|
||||||
Spezifische Dateitypen und Pfade:
|
- `client/custom/src/` - Frontend JavaScript (Views, Module)
|
||||||
entityDefs/{EntityType}.json: Definiert Entitäten (z. B. Account, Contact oder custom wie Project). Pfad: custom/Espo/Custom/Resources/metadata/entityDefs/Account.json.
|
- `client/custom/css/` - Custom Stylesheets
|
||||||
Kontrolliert: Felder, Beziehungen (Links), Indizes, Collections (z. B. Sortierung in Listen).
|
- `custom/scripts/` - Wartungs-Scripts (Rebuild, Workflow-Manager)
|
||||||
clientDefs/{EntityType}.json: Definiert Frontend-Konfigurationen für Entitäten. Pfad: custom/Espo/Custom/Resources/metadata/clientDefs/Account.json.
|
- `custom/workflows/` - Versionierte Workflow-Definitionen
|
||||||
Kontrolliert: Views (z. B. Edit-View), Controller, Modelle, Setup-Handler für dynamische UI-Anpassungen.
|
|
||||||
layouts/{EntityType}/{LayoutType}.json: Definiert UI-Layouts (z. B. Detail-View, List-View). Pfad: custom/Espo/Custom/Resources/layouts/Account/detail.json.
|
|
||||||
LayoutTypes: detail, list, edit, kanban, etc.
|
|
||||||
fields/{FieldType}.json: Globale Feld-Definitionen (z. B. für Address oder Phone). Pfad: custom/Espo/Custom/Resources/metadata/fields/address.json.
|
|
||||||
Kontrolliert: Feldtypen, Views für spezifische Felder (z. B. custom View für Phone mit Click-to-Call).
|
|
||||||
scopes/{EntityType}.json: Definiert Entity-Scopes (z. B. ob eine Entität importierbar ist). Pfad: custom/Espo/Custom/Resources/metadata/scopes/Project.json.
|
|
||||||
Andere (weniger häufig): aclDefs/ für Zugriffsrechte, selectDefs/ für Filter, recordDefs/ für Record-spezifische Logik.
|
|
||||||
|
|
||||||
Falls die KI ein neues Modul erstellt: custom/Espo/Modules/{ModuleName}/Resources/metadata/ – ähnliche Struktur, aber modular getrennt.
|
## Rebuild-Prozess
|
||||||
docs.espocrm.com
|
|
||||||
2. Dateiformate und JSON-Strukturen
|
|
||||||
|
|
||||||
Alle Dateien sind im JSON-Format. Die KI muss gültiges JSON parsen und schreiben (z. B. mit Bibliotheken wie json in Python). Strukturen sind hierarchisch: Objekte für Felder/Links, Arrays für Optionen/Listen.
|
**WICHTIG:** Nach jeder Änderung an Custom-Dateien muss ein Rebuild durchgeführt werden!
|
||||||
|
|
||||||
entityDefs/{EntityType}.json (Format-Beispiel für eine Entität wie Account):
|
### Check & Rebuild Script (Empfohlen)
|
||||||
JSON
|
|
||||||
|
|
||||||
|
**Zentrales Tool:** `custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
|
Dieses Script sollte **IMMER** verwendet werden (nicht manueller Rebuild). Es führt automatisch aus:
|
||||||
|
|
||||||
|
✅ **Validierungen:**
|
||||||
|
- JSON-Syntax-Prüfung aller `.json` Dateien im `custom/` Verzeichnis
|
||||||
|
- Dateirechte-Prüfung (`www-data:www-data` Owner)
|
||||||
|
- System-Checks (Cache-Verzeichnis, Logs-Verzeichnis)
|
||||||
|
|
||||||
|
✅ **Automatische Korrekturen:**
|
||||||
|
- Setzt fehlerhafte Dateirechte auf `www-data:www-data`
|
||||||
|
- Korrigiert Verzeichnis-Permissions (775) und Datei-Permissions (664)
|
||||||
|
|
||||||
|
✅ **Rebuild:**
|
||||||
|
- Merged alle Custom-Metadata mit Core-Definitionen
|
||||||
|
- Aktualisiert Datenbank-Schema (neue Felder, Tabellen, Indizes)
|
||||||
|
- Leert Cache-Verzeichnis
|
||||||
|
- Regeneriert Frontend-Assets
|
||||||
|
|
||||||
|
**Verwendung:**
|
||||||
|
```bash
|
||||||
|
# Im EspoCRM-Root-Verzeichnis ausführen
|
||||||
|
./custom/scripts/check_and_rebuild.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ausgabe:**
|
||||||
|
- ✓ Grün: Alles in Ordnung, Rebuild erfolgreich
|
||||||
|
- ⚠ Gelb: Warnungen, Rebuild wird trotzdem ausgeführt
|
||||||
|
- ✗ Rot: Fehler (z.B. ungültiges JSON), Rebuild wird NICHT ausgeführt
|
||||||
|
|
||||||
|
**Bei Fehlern:**
|
||||||
|
- JSON-Syntax-Fehler werden mit Datei und Zeilennummer angezeigt
|
||||||
|
- Dateirechte-Probleme werden automatisch korrigiert
|
||||||
|
- System-Fehler (fehlende Verzeichnisse) müssen manuell behoben werden
|
||||||
|
|
||||||
|
### Wann Rebuild erforderlich?
|
||||||
|
|
||||||
|
**Backend-Änderungen:**
|
||||||
|
- ✅ entityDefs, clientDefs, layouts, scopes bearbeitet
|
||||||
|
- ✅ Formula-Scripts erstellt/geändert
|
||||||
|
- ✅ i18n-Dateien aktualisiert
|
||||||
|
- ✅ Custom PHP-Klassen hinzugefügt
|
||||||
|
- ✅ CSS in app/client.json registriert
|
||||||
|
|
||||||
|
**Frontend-Änderungen:**
|
||||||
|
- ✅ JavaScript Views erstellt/geändert
|
||||||
|
- ✅ CSS-Dateien hinzugefügt
|
||||||
|
- ⚠️ Zusätzlich Browser Hard Refresh (Ctrl+Shift+R) erforderlich!
|
||||||
|
|
||||||
|
**Workflows:**
|
||||||
|
- ❌ Kein Rebuild nötig (Import über workflow_manager.php)
|
||||||
|
|
||||||
|
### Was der Rebuild bewirkt
|
||||||
|
|
||||||
|
1. **Metadata-Merging:** Kombiniert Custom-Definitionen mit Core-Definitionen
|
||||||
|
2. **Datenbank-Schema-Update:** Erstellt neue Tabellen/Spalten/Indizes basierend auf entityDefs
|
||||||
|
3. **Cache-Bereinigung:** Löscht gecachte Metadata, Views, Templates
|
||||||
|
4. **Frontend-Build:** Regeneriert JavaScript/CSS-Bundles
|
||||||
|
5. **ORM-Update:** Aktualisiert Entity-Klassen und Repositories
|
||||||
|
|
||||||
|
### Manuelle Dateirechte-Korrektur
|
||||||
|
|
||||||
|
Falls `check_and_rebuild.sh` Rechte-Probleme nicht beheben kann:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chown -R www-data:www-data custom/ client/custom/ data/
|
||||||
|
sudo find custom/ -type f -name "*.json" -exec chmod 664 {} \;
|
||||||
|
sudo find custom/ -type d -exec chmod 775 {} \;
|
||||||
|
sudo find client/custom/ -type f -exec chmod 664 {} \;
|
||||||
|
sudo find client/custom/ -type d -exec chmod 775 {} \;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dateiformate und JSON-Strukturen
|
||||||
|
|
||||||
|
Alle Metadata-Dateien sind im JSON-Format. Die Strukturen sind hierarchisch: Objekte für Felder/Links, Arrays für Optionen/Listen.
|
||||||
|
|
||||||
|
**Detaillierte Verzeichnisstruktur:** Siehe `/custom/CUSTOM_DIRECTORY.md`
|
||||||
|
|
||||||
|
### entityDefs/{EntityType}.json
|
||||||
|
|
||||||
|
**Format-Beispiel:**
|
||||||
|
```json
|
||||||
{
|
{
|
||||||
"fields": {
|
"fields": {
|
||||||
"name": {
|
"name": {
|
||||||
@@ -88,20 +166,55 @@ Alle Dateien sind im JSON-Format. Die KI muss gültiges JSON parsen und schreibe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Felder (fields): Schlüssel = Feldname, Wert = Objekt mit type (z. B. varchar, enum, link), required (bool), options (Array für Enums), etc.
|
**Wichtige Eigenschaften:**
|
||||||
Links: Beziehungen (belongsTo für 1:1, hasMany für 1:N, etc.).
|
- `fields` - Feldtypen (varchar, enum, link, etc.), Validierungen, Optionen
|
||||||
Collection: Für Listen-Views (Sortierung, Filter).
|
- `links` - Beziehungen zwischen Entitäten (belongsTo, hasMany, hasOne)
|
||||||
Auslösen: Hinzufügen eines Felds triggert bei Rebuild eine Datenbankänderung (neue Spalte in der Tabelle). Beziehungen erstellen Middle-Tables bei Many-to-Many.
|
- `collection` - Listen-View-Einstellungen (Sortierung, Filter)
|
||||||
**WICHTIG - Bidirektionale Relationships**: Bei hasMany-Relationships (z. B. viele Contacts zu einer Entität) müssen **beide Seiten** definiert werden:
|
- `indexes` - Datenbank-Performance-Optimierung
|
||||||
- In Entität A: Link mit `relationName` und `foreign` (zeigt auf Link-Namen in Entität B)
|
|
||||||
- In Entität B (z. B. Contact): Link mit **derselben** `relationName` und `foreign` (zeigt auf Link-Namen in Entität A)
|
|
||||||
- Beispiel: `CVmhMietverhltnis` hat Link `contactsMietverhltnis` mit relationName `cVmhMietverhltnisContact`; `Contact` hat Link `cVmhMietverhltnisesContact` mit derselben relationName und foreign `contactsMietverhltnis`.
|
|
||||||
- Fehlt eine Seite, gibt EspoCRM 404-Fehler "Link does not exist" zurück.
|
|
||||||
docs.espocrm.com
|
|
||||||
|
|
||||||
clientDefs/{EntityType}.json (Format-Beispiel):
|
**KRITISCH - Bidirektionale Relationships:**
|
||||||
JSON
|
|
||||||
|
Bei hasMany-Relationships müssen **BEIDE Seiten** definiert werden:
|
||||||
|
|
||||||
|
**Beispiel:** Contact ↔ Mietverhältnis
|
||||||
|
|
||||||
|
```json
|
||||||
|
// custom/Espo/Custom/Resources/metadata/entityDefs/CVmhMietverhltnis.json
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"contactsMietverhltnis": {
|
||||||
|
"type": "hasMany",
|
||||||
|
"relationName": "cVmhMietverhltnisContact",
|
||||||
|
"foreign": "cVmhMietverhltnisContact",
|
||||||
|
"entity": "Contact"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom/Espo/Custom/Resources/metadata/entityDefs/Contact.json
|
||||||
|
{
|
||||||
|
"links": {
|
||||||
|
"cVmhMietverhltnisContact": {
|
||||||
|
"type": "hasMany",
|
||||||
|
"relationName": "cVmhMietverhltnisContact",
|
||||||
|
"foreign": "contactsMietverhltnis",
|
||||||
|
"entity": "CVmhMietverhltnis"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtig:**
|
||||||
|
- `relationName` muss auf **beiden Seiten identisch** sein
|
||||||
|
- `foreign` zeigt auf den Link-Namen der **Gegenseite**
|
||||||
|
- Fehlt eine Seite → **"404 Link does not exist"-Fehler**
|
||||||
|
|
||||||
|
### clientDefs/{EntityType}.json
|
||||||
|
|
||||||
|
**Format-Beispiel:**
|
||||||
|
```json
|
||||||
|
|
||||||
{
|
{
|
||||||
"controller": "controllers/record",
|
"controller": "controllers/record",
|
||||||
@@ -120,14 +233,18 @@ JSON
|
|||||||
"record/detail": ["custom:handlers/my-detail-handler"]
|
"record/detail": ["custom:handlers/my-detail-handler"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Views/RecordViews: Pfade zu JS-Views (z. B. "custom:views/account/detail" für custom View).
|
**Wichtige Eigenschaften:**
|
||||||
ViewSetupHandlers: Arrays von Handlern für dynamische Anpassungen (z. B. Feld-Updates).
|
- `views`/`recordViews` - Pfade zu JavaScript Views (Custom mit Präfix `custom:`)
|
||||||
Auslösen: Ändert Frontend-Rendering (z. B. neue View-Modi wie Kanban).
|
- `viewSetupHandlers` - Dynamische View-Anpassungen
|
||||||
forum.espocrm.com
|
- `filterList` - Report-Filter-Integration (mit `__APPEND__`)
|
||||||
|
- `sidePanels` - Report-Panels für Side-Panel
|
||||||
|
|
||||||
layouts/{EntityType}/detail.json (Format-Beispiel für Detail-View):
|
### layouts/{EntityType}/{LayoutType}.json
|
||||||
JSON
|
|
||||||
|
**Format-Beispiel für Detail-View:**
|
||||||
|
```json
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@@ -149,20 +266,215 @@ JSON
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
```
|
||||||
|
|
||||||
Arrays von Panels (Objekte mit label und rows), rows sind Arrays von Zellen (Objekte mit name für Felder).
|
**Struktur:**
|
||||||
Auslösen: Ändert Feldanordnung in Views; unterstützt Parameter wie width, notSortable.
|
- Arrays von Panels (Objekte mit `label` und `rows`)
|
||||||
docs.espocrm.com
|
- `rows` sind Arrays von Zellen (Objekte mit `name` für Felder)
|
||||||
|
- Unterstützt Parameter: `width`, `notSortable`, `customLabel`
|
||||||
|
|
||||||
Spezielle Features:
|
**Spezielle Features:**
|
||||||
APPEND: In Arrays als erstes Element einfügen, um bestehende Werte zu erweitern (z. B. options: ["APPEND", "NewOption"]).
|
- `__APPEND__` - Als erstes Array-Element einfügen, um bestehende Werte zu erweitern
|
||||||
layoutAvailabilityList: Array für Feld-Sichtbarkeit in Layouts (z. B. ["list", "detail"]).
|
- `layoutAvailabilityList` - Array für Feld-Sichtbarkeit in Layouts
|
||||||
layoutIgnoreList: Zu ignorierende Layouts.
|
- `layoutIgnoreList` - Zu ignorierende Layouts
|
||||||
|
|
||||||
|
## Workflow-Verwaltung
|
||||||
|
|
||||||
|
EspoCRM bietet zwei Workflow-Typen für Prozessautomatisierung:
|
||||||
|
|
||||||
|
|
||||||
|
### 1. 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`, `wasNotEqual`
|
||||||
|
|
||||||
|
**Aktionen:**
|
||||||
|
- `sendEmail` - E-Mail versenden
|
||||||
|
- `createEntity` - Record erstellen
|
||||||
|
- `updateEntity` - Record aktualisieren
|
||||||
|
- `relateTo` / `unrelateFrom` - Verknüpfungen
|
||||||
|
- `createNotification` - Benachrichtigung
|
||||||
|
|
||||||
|
### 2. BPM Flowcharts (Komplex)
|
||||||
|
|
||||||
|
Visuelle Workflows mit BPMN 2.0-Standard für komplexe, mehrstufige Geschäftsprozesse.
|
||||||
|
|
||||||
|
**Komponenten:**
|
||||||
|
- Start-Events: Signal, Conditional, Timer
|
||||||
|
- Gateways: Exclusive, Inclusive, Parallel
|
||||||
|
- Tasks, End-Events
|
||||||
|
|
||||||
|
**Verwendung:** Über visuellen Designer im Admin-Interface
|
||||||
|
|
||||||
|
### Workflow-Dateien
|
||||||
|
|
||||||
|
**Speicherort:** `custom/workflows/*.json`
|
||||||
|
|
||||||
|
Workflow-Definitionen werden als JSON versioniert und über Git verwaltet.
|
||||||
|
|
||||||
|
**Format-Dokumentation:** Siehe `custom/workflows/README.md`
|
||||||
|
|
||||||
|
### Workflow Manager Script
|
||||||
|
|
||||||
|
**Tool:** `custom/scripts/workflow_manager.php`
|
||||||
|
|
||||||
|
Kommandozeilen-Tool für Workflow-Verwaltung (Simple und BPM).
|
||||||
|
|
||||||
|
#### 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 JSON-Datei. Unterstützt beide Workflow-Typen. Erstellt automatisch 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 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",
|
||||||
|
"category": "Kategorie-Name",
|
||||||
|
"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:**
|
||||||
|
- `category` - Workflow-Kategorie für bessere Organisation
|
||||||
|
- `comparison` - Vergleichsoperator
|
||||||
|
- `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": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Workflow-Entwicklung Best Practices
|
||||||
|
|
||||||
|
1. **Versionierung:** Workflows als JSON im `custom/workflows/` Verzeichnis versionieren
|
||||||
|
2. **Naming Convention:** Beschreibende Namen mit Präfix (z.B. `vmh-erstberatung-abschliessen.json`)
|
||||||
|
3. **Entwicklungsprozess:**
|
||||||
|
- Workflow-JSON in `custom/workflows/` erstellen
|
||||||
|
- Mit `workflow_manager.php import` einspielen
|
||||||
|
- Im Admin-Interface testen und bei Bedarf anpassen
|
||||||
|
- Mit `export` aktualisierten Workflow sichern
|
||||||
|
- JSON-Datei im Repository committen
|
||||||
|
4. **Backup:** Regelmäßig Export wichtiger Workflows durchführen
|
||||||
|
5. **Dokumentation:** Description-Feld aussagekräftig füllen
|
||||||
|
|
||||||
|
### Beispiel-Workflow
|
||||||
|
|
||||||
|
**Szenario:** E-Mail bei Status-Wechsel zu "Warte auf Mandatierung"
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "simple",
|
||||||
|
"name": "vmh-erstberatung-abschliessen",
|
||||||
|
"entity_type": "CVmhErstgespraech",
|
||||||
|
"trigger_type": "afterRecordSaved",
|
||||||
|
"is_active": true,
|
||||||
|
"conditions_all": [
|
||||||
|
{
|
||||||
|
"comparison": "equals",
|
||||||
|
"fieldToCompare": "status",
|
||||||
|
"value": "Warte auf Mandatierung"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"comparison": "changed",
|
||||||
|
"fieldToCompare": "status"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"actions": [
|
||||||
|
{
|
||||||
|
"type": "sendEmail",
|
||||||
|
"to": "targetEntity",
|
||||||
|
"emailTemplateId": "template-id-here"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Internationalisierung (i18n) und Tooltips
|
## Internationalisierung (i18n) und Tooltips
|
||||||
|
|
||||||
**KRITISCH: Mehrsprachige Tooltip-Verwaltung**
|
|
||||||
|
|
||||||
EspoCRM verwendet ein hierarchisches Mehrsprachen-System mit **en_US als Basis-Fallback**:
|
EspoCRM verwendet ein hierarchisches Mehrsprachen-System mit **en_US als Basis-Fallback**:
|
||||||
|
|
||||||
1. **Sprachpriorität**: en_US → aktuelle Sprache (z.B. de_DE)
|
1. **Sprachpriorität**: en_US → aktuelle Sprache (z.B. de_DE)
|
||||||
@@ -608,20 +920,7 @@ Für KI-gestützte Workflow-Erstellung:
|
|||||||
3. Im Admin-Interface testen und bei Bedarf anpassen
|
3. Im Admin-Interface testen und bei Bedarf anpassen
|
||||||
4. Mit `export` Befehl aktualisierten Workflow sichern
|
4. Mit `export` Befehl aktualisierten Workflow sichern
|
||||||
5. JSON-Datei im Repository committen
|
5. JSON-Datei im Repository committen
|
||||||
Rebuild auslösen:
|
## Projektziele und Zukunftsvision: "Vermieterhelden"
|
||||||
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")).
|
|
||||||
Effekt: Mergt alle Metadata, aktualisiert DB-Schema, cached Views. Ohne Rebuild bleiben Änderungen unsichtbar.
|
|
||||||
docs.espocrm.com
|
|
||||||
|
|
||||||
4. Best Practices für KI-Implementation
|
|
||||||
|
|
||||||
Workflow: 1. Datei lesen/parsen. 2. Modifizieren (z. B. Feld hinzufügen). 3. Validieren (JSON-Schema prüfen). 4. Speichern. 5. Rebuild triggern.
|
|
||||||
Sicherheit: Backups erstellen, Änderungen loggen. Vermeide Core-Änderungen.
|
|
||||||
Automatisierung: KI könnte Skripte generieren (z. B. Python mit json und os für Dateizugriff) oder direkt integriert werden (z. B. in einem Custom-Modul mit PHP-Aufrufen).
|
|
||||||
Grenzen: Keine out-of-the-box Automatisierung in Docs; Community erwähnt Skripte für Massen-Edits, aber nichts KI-spezifisch.
|
|
||||||
|
|
||||||
5. Projektziele und Zukunftsvision: "Vermieterhelden"
|
|
||||||
|
|
||||||
Das Projekt "Vermieterhelden" ist ein maßgeschneidertes Backend-System auf Basis von EspoCRM für eine Anwaltskanzlei, spezialisiert auf die Durchführung und Verwaltung von immobilienrechtlichen Klagen (z. B. Räumungsklagen, Mietinkasso). Der aktuelle Fokus liegt auf der strukturierten Verwaltung von Stammdaten (Entitäten wie Mietverhältnisse, Mietobjekte, Beteiligte, Dokumente und Klagen) und der Abbildung von rechtlichen Workflows (z. B. automatisierte Tasks bei Statusänderungen, Fristen-Überwachung).
|
Das Projekt "Vermieterhelden" ist ein maßgeschneidertes Backend-System auf Basis von EspoCRM für eine Anwaltskanzlei, spezialisiert auf die Durchführung und Verwaltung von immobilienrechtlichen Klagen (z. B. Räumungsklagen, Mietinkasso). Der aktuelle Fokus liegt auf der strukturierten Verwaltung von Stammdaten (Entitäten wie Mietverhältnisse, Mietobjekte, Beteiligte, Dokumente und Klagen) und der Abbildung von rechtlichen Workflows (z. B. automatisierte Tasks bei Statusänderungen, Fristen-Überwachung).
|
||||||
|
|
||||||
@@ -655,125 +954,43 @@ Um EspoCRM anzupassen, bearbeite JSON-Dateien im custom/-Verzeichnis. Änderunge
|
|||||||
LayoutTypes: detail, list, edit, etc. – Passe Views an, um UI zu optimieren.
|
LayoutTypes: detail, list, edit, etc. – Passe Views an, um UI zu optimieren.
|
||||||
|
|
||||||
Rebuild durchführen:
|
Rebuild durchführen:
|
||||||
Nach Änderungen muss ein Rebuild ausgeführt werden, um Caches zu leeren und Metadata neu zu mergen.
|
Nach Änderungen muss ein Rebuild durchgeführt werden.
|
||||||
CLI-Befehl (im Docker-Container): docker exec espocrm php /var/www/html/command.php Rebuild
|
Verwende: `./custom/scripts/check_and_rebuild.sh` (validiert JSON, prüft Rechte, führt Rebuild durch)
|
||||||
Alternative: Web-Interface > Administration > Clear Cache & Rebuild.
|
Siehe Abschnitt "Rebuild-Prozess" für Details.
|
||||||
|
|
||||||
7. Panel-Labels und Übersetzungen
|
## Panel-Labels und Übersetzungen
|
||||||
|
|
||||||
Um Relationship-Panels und Links korrekt zu beschriften, müssen Labels in den i18n-Sprachdateien definiert werden.
|
Um Relationship-Panels und Links korrekt zu beschriften, müssen Labels in den i18n-Sprachdateien definiert werden.
|
||||||
|
|
||||||
**Wichtig - Labels in allen Sprachen definieren**:
|
**Vollständige i18n-Dokumentation:** Siehe Abschnitt "Internationalisierung (i18n) und Tooltips"
|
||||||
- Labels müssen in **allen installierten Sprachen** definiert werden (z. B. de_DE UND en_US)
|
|
||||||
- Fehlende Labels in einer Sprache können dazu führen, dass die Beschriftung nicht funktioniert
|
|
||||||
- Selbst wenn die Hauptsprache de_DE ist, sollten en_US Labels immer mit definiert werden
|
|
||||||
|
|
||||||
**Labels müssen in zwei Sektionen stehen**:
|
**Kurzübersicht:**
|
||||||
- `fields`: Für die Anzeige als Feld
|
- Labels in **allen Sprachen** definieren (de_DE UND en_US)
|
||||||
- `links`: Für die Anzeige in Relationship-Panels
|
- Labels in **zwei Sektionen**: `fields` UND `links`
|
||||||
- Beide Sektionen müssen identische Werte haben
|
- Nach Änderungen: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
Pfade:
|
**Beispiel:**
|
||||||
- `custom/Espo/Custom/Resources/i18n/de_DE/{EntityType}.json` (deutsch)
|
```json
|
||||||
- `custom/Espo/Custom/Resources/i18n/en_US/{EntityType}.json` (englisch)
|
// custom/Espo/Custom/Resources/i18n/de_DE/CBeteiligte.json
|
||||||
|
{
|
||||||
|
"fields": {
|
||||||
|
"vmhvermieterbeteiligte": "Vermieter",
|
||||||
|
"vmhmieterbeteiligte": "Mieter"
|
||||||
|
},
|
||||||
|
"links": {
|
||||||
|
"vmhvermieterbeteiligte": "Vermieter",
|
||||||
|
"vmhmieterbeteiligte": "Mieter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Struktur (Beispiel CBeteiligte.json):
|
**Tooltips:**
|
||||||
```json
|
|
||||||
{
|
|
||||||
"fields": {
|
|
||||||
"address": "Adresse",
|
|
||||||
"vmhvermieterbeteiligte": "Vermieter",
|
|
||||||
"vmhmieterbeteiligte": "Mieter",
|
|
||||||
"vmhRumungsklagesKlaeger": "Kläger"
|
|
||||||
},
|
|
||||||
"links": {
|
|
||||||
"calls": "Anrufe",
|
|
||||||
"tasks": "Aufgaben",
|
|
||||||
"vmhvermieterbeteiligte": "Vermieter",
|
|
||||||
"vmhmieterbeteiligte": "Mieter",
|
|
||||||
"vmhRumungsklagesKlaeger": "Kläger"
|
|
||||||
},
|
|
||||||
"labels": {
|
|
||||||
"Create CBeteiligte": "Beteiligte erstellen"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Best Practice:
|
- Aktivierung: `"tooltip": true` in entityDef setzen
|
||||||
- Bei jeder neuen Relationship immer beide Sprachen (de_DE und en_US) aktualisieren
|
- Definition in `tooltips`-Sektion der i18n-Dateien
|
||||||
- Link-Namen in fields UND links eintragen
|
- **Vollständige Dokumentation:** Siehe Abschnitt "Internationalisierung (i18n) und Tooltips"
|
||||||
- Nach Änderungen Rebuild durchführen
|
|
||||||
- Das Admin UI macht dies automatisch, manuelle Änderungen müssen beide Dateien berücksichtigen
|
|
||||||
Effekt: Aktualisiert DB-Schema, Views und entfernt alte Caches. Ohne Rebuild sind Änderungen unsichtbar.
|
|
||||||
Hinweis: Führe den Befehl auf dem Host aus, da der Container den PHP-Zugang hat.
|
|
||||||
|
|
||||||
**Tooltips für Felder definieren**:
|
## Custom JavaScript & CSS Integration
|
||||||
- Tooltips sind Hilfe-Texte, die beim Hovern über das Info-Icon neben einem Feld erscheinen
|
|
||||||
- Tooltips werden in einem separaten `tooltips`-Objekt in den i18n-Dateien definiert
|
|
||||||
- Das Feld muss in der entityDef mit `"tooltip": true` markiert sein, damit das Icon angezeigt wird
|
|
||||||
|
|
||||||
Aktivierung in entityDef (entityDefs/{EntityType}.json):
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"fields": {
|
|
||||||
"lage": {
|
|
||||||
"type": "varchar",
|
|
||||||
"required": false,
|
|
||||||
"maxLength": 255,
|
|
||||||
"tooltip": true,
|
|
||||||
"isCustom": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Definition in i18n-Dateien (i18n/de_DE/{EntityType}.json):
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"fields": {
|
|
||||||
"lage": "Lage"
|
|
||||||
},
|
|
||||||
"links": {},
|
|
||||||
"labels": {},
|
|
||||||
"tooltips": {
|
|
||||||
"lage": "Lage innerhalb des Objekts (z.B. EG links, 1. OG rechts)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Best Practice:
|
|
||||||
- Tooltip-Texte sollten kurz und prägnant sein (1-2 Sätze)
|
|
||||||
- Tooltips in allen Sprachen definieren (de_DE, en_US, etc.)
|
|
||||||
- Nach Änderungen Rebuild durchführen
|
|
||||||
- Tooltips werden nur angezeigt, wenn `"tooltip": true` in der entityDef gesetzt ist
|
|
||||||
|
|
||||||
## 8. Custom Scripts und Tools
|
|
||||||
|
|
||||||
Um die Entwicklung und Wartung zu erleichtern, wurden benutzerdefinierte Scripts im `custom/scripts/`-Ordner abgelegt. Diese Scripts überleben EspoCRM-Updates, da sie außerhalb der Core-Dateien liegen.
|
|
||||||
|
|
||||||
### Verfügbare Scripts:
|
|
||||||
|
|
||||||
#### workflow_manager.php
|
|
||||||
- **Zweck**: Verwaltung von BPMN-Workflows in EspoCRM. Ermöglicht das Lesen, Bearbeiten, Löschen, Ausführen und Testen von Workflows direkt über die Datenbank.
|
|
||||||
- **Bedienung**:
|
|
||||||
- Ausführen im EspoCRM-Container: `docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php <aktion> [parameter]`
|
|
||||||
- Aktionen:
|
|
||||||
- `list`: Listet alle verfügbaren Workflows auf (ID und Name).
|
|
||||||
- `read <id>`: Zeigt detaillierte Informationen zu einem Workflow (inkl. JSON-Data).
|
|
||||||
- `delete <id>`: Löscht einen Workflow (mit Bestätigung).
|
|
||||||
- `edit <id> <json_data>`: Bearbeitet die Workflow-Data (übergib gültiges JSON).
|
|
||||||
- `execute <workflow_id> <record_id>`: Führt einen Workflow manuell für einen Record aus (simuliert Trigger).
|
|
||||||
- `test <id>`: Testet Workflow-Bedingungen (simuliert Auswertung).
|
|
||||||
- **Beispiele**:
|
|
||||||
- `docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php list`
|
|
||||||
- `docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php read 68df9eb6b8d460186`
|
|
||||||
- `docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php execute 68df9eb6b8d460186 some_record_id`
|
|
||||||
- **Hinweise**:
|
|
||||||
- Sichere Backups vor Lösch- oder Edit-Operationen.
|
|
||||||
- Für komplexe Änderungen die EspoCRM-UI verwenden.
|
|
||||||
- Execute simuliert nur einfache Aktionen; für vollständige Ausführung EspoCRM-API nutzen.
|
|
||||||
|
|
||||||
## 8. Troubleshooting
|
|
||||||
|
|
||||||
### 404-Fehler "Link does not exist"
|
### 404-Fehler "Link does not exist"
|
||||||
- **Symptom**: HTTP 404-Fehler in Logs: "Link does not exist" beim Versuch, eine Relationship anzuzeigen oder zu verknüpfen.
|
- **Symptom**: HTTP 404-Fehler in Logs: "Link does not exist" beim Versuch, eine Relationship anzuzeigen oder zu verknüpfen.
|
||||||
@@ -800,7 +1017,7 @@ Um die Entwicklung und Wartung zu erleichtern, wurden benutzerdefinierte Scripts
|
|||||||
"entity": "CBeteiligte"
|
"entity": "CBeteiligte"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- Nach Korrektur: `docker exec espocrm php /var/www/html/command.php Rebuild` ausführen.
|
- Nach Korrektur: `./custom/scripts/check_and_rebuild.sh` ausführen.
|
||||||
|
|
||||||
### 500-Fehler bei Layout-Änderungen
|
### 500-Fehler bei Layout-Änderungen
|
||||||
- **Symptom**: HTTP 500-Fehler beim Versuch, Layouts in der EspoCRM-UI zu bearbeiten (z.B. "Permission denied for custom/Espo/Custom/Resources/layouts/...").
|
- **Symptom**: HTTP 500-Fehler beim Versuch, Layouts in der EspoCRM-UI zu bearbeiten (z.B. "Permission denied for custom/Espo/Custom/Resources/layouts/...").
|
||||||
@@ -815,12 +1032,7 @@ Um die Entwicklung und Wartung zu erleichtern, wurden benutzerdefinierte Scripts
|
|||||||
```bash
|
```bash
|
||||||
./custom/scripts/check_and_rebuild.sh
|
./custom/scripts/check_and_rebuild.sh
|
||||||
```
|
```
|
||||||
Das Script prüft automatisch auf häufige Fehler (JSON-Syntax, Dateirechte) und führt bei Fehlerfreiheit den Rebuild durch.
|
Das Script prüft automatisch auf häufige Fehler (JSON-Syntax, Dateirechte) und führt bei Fehlerfreiheit den Rebuild durch. Siehe Abschnitt "Rebuild-Prozess" für Details.
|
||||||
|
|
||||||
- Manueller Rebuild (nur falls Script nicht funktioniert):
|
|
||||||
```bash
|
|
||||||
docker exec espocrm php /var/www/html/command.php Rebuild
|
|
||||||
```
|
|
||||||
|
|
||||||
- Logs prüfen: `tail -n 100 /var/lib/docker/volumes/vmh-espocrm_espocrm/_data/data/logs/espo-YYYY-MM-DD.log`
|
- Logs prüfen: `tail -n 100 /var/lib/docker/volumes/vmh-espocrm_espocrm/_data/data/logs/espo-YYYY-MM-DD.log`
|
||||||
- Bei Relationship-Problemen: Logs nach "404" und "Link does not exist" durchsuchen: `tail -n 500 /var/lib/docker/volumes/vmh-espocrm_espocrm/_data/data/logs/espo-$(date +%Y-%m-%d).log | grep -A 3 "404\|Link does not exist"`
|
- Bei Relationship-Problemen: Logs nach "404" und "Link does not exist" durchsuchen: `tail -n 500 /var/lib/docker/volumes/vmh-espocrm_espocrm/_data/data/logs/espo-$(date +%Y-%m-%d).log | grep -A 3 "404\|Link does not exist"`
|
||||||
@@ -1041,14 +1253,11 @@ Report-Panels zeigen Listen von Entitäten in Side-Panels der Detail-View an. Si
|
|||||||
### Nach Änderungen:
|
### Nach Änderungen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Rebuild durchführen
|
# Rebuild durchführen (validiert JSON, prüft Rechte)
|
||||||
docker exec espocrm php /var/www/html/command.php Rebuild
|
|
||||||
|
|
||||||
# Oder Check-Script verwenden
|
|
||||||
./custom/scripts/check_and_rebuild.sh
|
./custom/scripts/check_and_rebuild.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## 10. Portal-Freigabe-System
|
## Portal-Freigabe-System
|
||||||
|
|
||||||
Um Entitäten für Portalnutzer (Contact-Entität) freizugeben, wurde ein konsistentes Freigabe-System implementiert:
|
Um Entitäten für Portalnutzer (Contact-Entität) freizugeben, wurde ein konsistentes Freigabe-System implementiert:
|
||||||
|
|
||||||
@@ -1117,11 +1326,186 @@ Um Entitäten für Portalnutzer (Contact-Entität) freizugeben, wurde ein konsis
|
|||||||
- `selectPrimaryFilterName: "portalUsers"` filtert automatisch auf Portal-User
|
- `selectPrimaryFilterName: "portalUsers"` filtert automatisch auf Portal-User
|
||||||
- Tab "Freigabe für" sollte immer der erste Tab im Bottom-Panel sein (index: 0)
|
- Tab "Freigabe für" sollte immer der erste Tab im Bottom-Panel sein (index: 0)
|
||||||
- Style "warning" hebt das Panel visuell hervor
|
- Style "warning" hebt das Panel visuell hervor
|
||||||
- Nach Änderungen immer Rebuild durchführen und beide Seiten der Relationship definieren
|
- Nach Änderungen: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
- Beide Seiten der Relationship müssen in entityDefs definiert sein
|
||||||
|
|
||||||
---
|
## Troubleshooting
|
||||||
|
|
||||||
## Custom JavaScript & CSS Integration
|
### "Link does not exist" (404-Fehler)
|
||||||
|
**Symptom:** HTTP 404-Fehler in Logs beim Versuch, eine Relationship anzuzeigen oder zu verknüpfen.
|
||||||
|
|
||||||
|
**Ursache:** Bei hasMany-Relationships fehlt die Definition auf einer Seite der Beziehung.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Prüfe beide entityDefs-Dateien (z.B. `CBeteiligte.json` UND `Contact.json`)
|
||||||
|
2. Stelle sicher, dass beide Seiten den Link mit derselben `relationName` definieren
|
||||||
|
3. Das `foreign`-Attribut muss jeweils auf den Link-Namen der Gegenseite zeigen
|
||||||
|
|
||||||
|
**Beispiel:**
|
||||||
|
```json
|
||||||
|
// In CBeteiligte.json:
|
||||||
|
"contactsBeteiligte": {
|
||||||
|
"type": "hasMany",
|
||||||
|
"relationName": "cBeteiligteContact",
|
||||||
|
"foreign": "cBeteiligteContact",
|
||||||
|
"entity": "Contact"
|
||||||
|
}
|
||||||
|
|
||||||
|
// In Contact.json:
|
||||||
|
"cBeteiligteContact": {
|
||||||
|
"type": "hasMany",
|
||||||
|
"relationName": "cBeteiligteContact",
|
||||||
|
"foreign": "contactsBeteiligte",
|
||||||
|
"entity": "CBeteiligte"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach Korrektur: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
|
### Tooltip zeigt nur Feldnamen
|
||||||
|
**Symptom:** Tooltip zeigt nur "iban" statt vollständiger Beschreibung.
|
||||||
|
|
||||||
|
**Ursache:** Fehlerhafte oder fehlende `en_US` i18n-Datei (en_US ist Fallback-Sprache).
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Existiert `custom/Espo/Custom/Resources/i18n/en_US/{Entity}.json`?
|
||||||
|
2. Enthält es fehlerhafte Tooltip-Definitionen?
|
||||||
|
3. Sind alle Tooltips konsistent über alle Sprachen?
|
||||||
|
4. Vervollständige en_US-Datei mit korrekten englischen Übersetzungen
|
||||||
|
|
||||||
|
**Korrekt:**
|
||||||
|
```json
|
||||||
|
// de_DE/{Entity}.json
|
||||||
|
{
|
||||||
|
"fields": {"iban": "IBAN"},
|
||||||
|
"tooltips": {"iban": "Internationale Bankkontonummer im Format DE89..."}
|
||||||
|
}
|
||||||
|
|
||||||
|
// en_US/{Entity}.json
|
||||||
|
{
|
||||||
|
"fields": {"iban": "IBAN"},
|
||||||
|
"tooltips": {"iban": "International Bank Account Number in format DE89..."}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach Korrektur: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
|
### Formula-Script wird nicht ausgeführt
|
||||||
|
**Symptom:** beforeSaveApiScript triggert nicht, keine Validierung.
|
||||||
|
|
||||||
|
**Ursache:** Script in `entityDefs` statt `formula/` abgelegt.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
- Erstelle separate Datei: `custom/Espo/Custom/Resources/metadata/formula/{Entity}.json`
|
||||||
|
- NICHT in `entityDefs/{Entity}.json` einfügen!
|
||||||
|
|
||||||
|
```json
|
||||||
|
// custom/Espo/Custom/Resources/metadata/formula/Entity.json
|
||||||
|
{
|
||||||
|
"beforeSaveApiScript": "if (field != null && field != '') { ... }"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach Korrektur: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
|
### CSS-Änderungen nicht sichtbar
|
||||||
|
**Symptom:** CSS-Änderungen werden nicht im Browser angezeigt.
|
||||||
|
|
||||||
|
**Ursache:** Browser-Cache oder fehlende Registrierung.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. CSS in `custom/Espo/Custom/Resources/metadata/app/client.json` registrieren:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cssList": ["__APPEND__", "client/custom/css/my-styles.css"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
2. `./custom/scripts/check_and_rebuild.sh` ausführen
|
||||||
|
3. Browser Hard Refresh (Ctrl+Shift+R / Cmd+Shift+R)
|
||||||
|
|
||||||
|
### "Permission denied" bei Layout-Bearbeitung
|
||||||
|
**Symptom:** HTTP 500-Fehler beim Versuch, Layouts über die UI zu bearbeiten.
|
||||||
|
|
||||||
|
**Ursache:** Falsche Dateirechte - `custom/`-Verzeichnis gehört `root` statt `www-data`.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
Das `check_and_rebuild.sh` Script prüft und korrigiert Dateirechte automatisch. Falls manuelle Korrektur nötig:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo chown -R www-data:www-data custom/ client/custom/
|
||||||
|
sudo find custom/ -type f -name "*.json" -exec chmod 664 {} \;
|
||||||
|
sudo find custom/ -type d -exec chmod 775 {} \;
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON-Syntax-Fehler
|
||||||
|
**Symptom:** Rebuild schlägt fehl, Script zeigt "Invalid JSON" Fehler.
|
||||||
|
|
||||||
|
**Ursache:** Ungültiges JSON (fehlende Kommas, Anführungszeichen, etc.).
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. `./custom/scripts/check_and_rebuild.sh` zeigt Datei und Zeilennummer an
|
||||||
|
2. JSON-Validator verwenden (z.B. jsonlint.com)
|
||||||
|
3. Häufige Fehler:
|
||||||
|
- Komma nach letztem Array/Object-Element
|
||||||
|
- Einfache statt doppelte Anführungszeichen
|
||||||
|
- Fehlende schließende Klammern
|
||||||
|
|
||||||
|
### "Unknown function" in Formula
|
||||||
|
**Symptom:** Error "Unknown function: xxx" beim Speichern.
|
||||||
|
|
||||||
|
**Ursache:** Funktion existiert nicht oder ist nicht registriert.
|
||||||
|
|
||||||
|
**Lösung:**
|
||||||
|
1. Für Custom-Funktionen: Registrierung in `app/formula.json` prüfen
|
||||||
|
2. `string\isEmpty()` existiert nicht → verwende `field != null && field != ''`
|
||||||
|
3. Nach Registrierung: `./custom/scripts/check_and_rebuild.sh`
|
||||||
|
|
||||||
|
### Logs prüfen
|
||||||
|
**Wichtige Log-Dateien:**
|
||||||
|
```bash
|
||||||
|
# Aktuelles Log (heutiges Datum)
|
||||||
|
tail -n 100 data/logs/espo-$(date +%Y-%m-%d).log
|
||||||
|
|
||||||
|
# Nach bestimmten Fehlern suchen
|
||||||
|
tail -n 500 data/logs/espo-*.log | grep -i "404\|500\|error\|exception"
|
||||||
|
|
||||||
|
# Formula-Script-Fehler
|
||||||
|
tail -n 200 data/logs/espo-*.log | grep -i "formula\|script"
|
||||||
|
|
||||||
|
# Relationship-Fehler
|
||||||
|
tail -n 500 data/logs/espo-*.log | grep -i "link does not exist"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Allgemeine Troubleshooting-Schritte
|
||||||
|
|
||||||
|
1. **Nach jeder Änderung:**
|
||||||
|
```bash
|
||||||
|
./custom/scripts/check_and_rebuild.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Bei Frontend-Problemen:**
|
||||||
|
- Browser Hard Refresh (Ctrl+Shift+R)
|
||||||
|
- Browser-Cache komplett leeren
|
||||||
|
- Inkognito-Modus testen
|
||||||
|
|
||||||
|
3. **Bei Backend-Problemen:**
|
||||||
|
- Logs prüfen (siehe oben)
|
||||||
|
- Dateirechte prüfen (`www-data:www-data`)
|
||||||
|
- JSON-Syntax validieren
|
||||||
|
|
||||||
|
4. **Bei Relationship-Problemen:**
|
||||||
|
- Beide Seiten der Relationship prüfen
|
||||||
|
- `relationName` identisch?
|
||||||
|
- `foreign` zeigt auf korrekten Link-Namen?
|
||||||
|
- Nach Rebuild: Cache manuell leeren falls nötig
|
||||||
|
|
||||||
|
**Vollständige Dokumentation zur Custom Directory Struktur:** Siehe `/custom/CUSTOM_DIRECTORY.md`
|
||||||
|
|
||||||
|
**JavaScript-Module:** `client/custom/src/modules/` - AMD-Module für wiederverwendbare Logik
|
||||||
|
|
||||||
|
**Custom Views:** `client/custom/src/views/` - Backbone.js Views für Entity-spezifisches UI
|
||||||
|
|
||||||
|
**CSS-Stylesheets:** `client/custom/css/` - Custom CSS (Registrierung in `app/client.json` erforderlich)
|
||||||
|
|
||||||
### JavaScript-Module einbinden
|
### JavaScript-Module einbinden
|
||||||
|
|
||||||
@@ -1211,7 +1595,9 @@ EspoCRM erlaubt Custom CSS über Metadata-Registrierung.
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**3. Rebuild durchführen** - CSS wird in gecachtes Bundle integriert
|
**Nach CSS-Änderungen:**
|
||||||
|
1. `./custom/scripts/check_and_rebuild.sh` ausführen
|
||||||
|
2. Browser Hard Refresh (Ctrl+Shift+R)
|
||||||
|
|
||||||
**CSS-Targeting-Strategien:**
|
**CSS-Targeting-Strategien:**
|
||||||
- **Feld-spezifisch:** `.cell[data-name="fieldName"]`
|
- **Feld-spezifisch:** `.cell[data-name="fieldName"]`
|
||||||
@@ -1235,10 +1621,10 @@ EspoCRM erlaubt Custom CSS über Metadata-Registrierung.
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Best Practices:**
|
**Best Practices:**
|
||||||
- CSS-Dateien in `client/custom/css/` oder `client/custom/modules/{module}/css/` ablegen
|
- CSS-Dateien in `client/custom/css/` ablegen
|
||||||
- `__APPEND__` verwendet um Core-CSS zu erweitern, nicht zu überschreiben
|
- `__APPEND__` verwenden um Core-CSS zu erweitern, nicht zu überschreiben
|
||||||
- Spezifische Selektoren verwenden um Kollisionen zu vermeiden
|
- Spezifische Selektoren verwenden um Kollisionen zu vermeiden
|
||||||
- Nach CSS-Änderungen: Rebuild + Hard Refresh (Browser Cache löschen)
|
- Nach CSS-Änderungen: `./custom/scripts/check_and_rebuild.sh` + Browser Hard Refresh
|
||||||
|
|
||||||
### RVG-Gebührenrechner (CVmhErstgespraech)
|
### RVG-Gebührenrechner (CVmhErstgespraech)
|
||||||
|
|
||||||
|
|||||||
@@ -1,121 +1,343 @@
|
|||||||
# EspoCRM Custom Directory - Übersicht
|
# EspoCRM Custom Directory - Vollständige Übersicht
|
||||||
|
|
||||||
## Verzeichnisstruktur
|
Dieses Dokument beschreibt die vollständige Struktur aller Custom-Verzeichnisse in EspoCRM. Für Workflow-Management, Formula-Scripts und andere Funktionalitäten siehe die Hauptdokumentation in `/README.md`.
|
||||||
|
|
||||||
|
## Vollständige Verzeichnisstruktur
|
||||||
|
|
||||||
```
|
```
|
||||||
custom/
|
custom/ # Backend Customizations
|
||||||
├── Espo/
|
├── Espo/
|
||||||
│ ├── Custom/ # Custom Entitäten, Services, Controller etc.
|
│ ├── Custom/ # Custom Entitäten, Services, Controller
|
||||||
│ └── Modules/ # Custom Module
|
│ │ ├── Classes/ # Custom PHP-Klassen
|
||||||
├── scripts/ # Custom PHP Scripts für Wartung/Verwaltung
|
│ │ │ └── FormulaFunctions/ # Custom Formula-Funktionen
|
||||||
│ ├── check_and_rebuild.sh
|
│ │ ├── Controllers/ # Custom Controller
|
||||||
│ └── workflow_manager.php
|
│ │ ├── Services/ # Custom Services
|
||||||
└── workflows/ # Workflow-Definitionen als JSON
|
│ │ ├── Repositories/ # Custom Repositories
|
||||||
├── README.md
|
│ │ └── Resources/
|
||||||
├── vmh-erstberatung-abschliessen.json
|
│ │ ├── metadata/ # Entity-, Field-, Client-Definitionen
|
||||||
|
│ │ │ ├── entityDefs/ # Entity-Definitionen (Felder, Links)
|
||||||
|
│ │ │ ├── clientDefs/ # Frontend-Konfigurationen
|
||||||
|
│ │ │ ├── selectDefs/ # Filter-Definitionen
|
||||||
|
│ │ │ ├── scopes/ # Entity-Scopes
|
||||||
|
│ │ │ ├── fields/ # Globale Feld-Definitionen
|
||||||
|
│ │ │ ├── formula/ # Formula-Scripts pro Entity
|
||||||
|
│ │ │ ├── recordDefs/ # Record-spezifische Logik
|
||||||
|
│ │ │ ├── aclDefs/ # Zugriffsrechte
|
||||||
|
│ │ │ └── app/ # App-weite Konfigurationen
|
||||||
|
│ │ │ ├── formula.json # Formula-Funktions-Registrierung
|
||||||
|
│ │ │ └── client.json # CSS/JS-Registrierung
|
||||||
|
│ │ ├── layouts/ # UI-Layout-Definitionen
|
||||||
|
│ │ │ └── {Entity}/
|
||||||
|
│ │ │ ├── detail.json # Detail-View-Layout
|
||||||
|
│ │ │ ├── list.json # List-View-Layout
|
||||||
|
│ │ │ ├── edit.json # Edit-View-Layout
|
||||||
|
│ │ │ └── bottomPanelsDetail.json # Bottom-Panels
|
||||||
|
│ │ └── i18n/ # Übersetzungen
|
||||||
|
│ │ ├── de_DE/ # Deutsche Übersetzungen
|
||||||
|
│ │ │ └── {Entity}.json # Labels, Links, Tooltips
|
||||||
|
│ │ └── en_US/ # Englische Übersetzungen (FALLBACK!)
|
||||||
|
│ │ └── {Entity}.json # MUSS vollständig sein
|
||||||
|
│ └── Modules/ # Custom Module (gekapselt)
|
||||||
|
│ └── {ModuleName}/
|
||||||
|
│ └── Resources/ # Gleiche Struktur wie Custom/Resources/
|
||||||
|
├── scripts/ # Wartungs- und Verwaltungs-Scripts
|
||||||
|
│ ├── check_and_rebuild.sh # Validierung + Rebuild + Rechteprüfung
|
||||||
|
│ └── workflow_manager.php # Workflow-Verwaltung (list, import, export, delete)
|
||||||
|
└── workflows/ # Workflow-Definitionen (versioniert)
|
||||||
|
├── README.md # Workflow-Format-Dokumentation
|
||||||
|
└── *.json # Workflow-Definitionen (Simple & BPM)
|
||||||
|
|
||||||
|
client/custom/ # Frontend Customizations
|
||||||
|
├── css/ # Custom CSS-Stylesheets
|
||||||
|
│ └── *.css # Muss in app/client.json registriert werden
|
||||||
|
├── src/
|
||||||
|
│ ├── modules/ # AMD JavaScript-Module
|
||||||
|
│ │ └── *.js # Wiederverwendbare Logik (z.B. Calculator)
|
||||||
|
│ └── views/ # Custom Backbone.js Views
|
||||||
|
│ └── {entity}/
|
||||||
|
│ ├── fields/ # Custom Field Views
|
||||||
|
│ │ └── {fieldname}.js # Erweitert Standard-Field-Views
|
||||||
|
│ ├── detail.js # Custom Detail-View
|
||||||
|
│ ├── edit.js # Custom Edit-View
|
||||||
|
│ └── list.js # Custom List-View
|
||||||
|
├── modules/ # Third-Party Extensions
|
||||||
|
│ ├── advanced/ # Advanced Pack Module
|
||||||
|
│ ├── link-button/ # Link-Button Extension
|
||||||
|
│ └── crm/ # CRM Module
|
||||||
|
└── res/ # Custom Frontend-Ressourcen
|
||||||
|
└── templates/ # Handlebars-Templates
|
||||||
```
|
```
|
||||||
|
|
||||||
## Zweck der Verzeichnisse
|
## Backend Customizations (custom/Espo/)
|
||||||
|
|
||||||
### custom/Espo/Custom/
|
### custom/Espo/Custom/Resources/metadata/
|
||||||
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/
|
Dies ist das Herzstück der EspoCRM-Customization. Alle JSON-Dateien hier werden rekursiv mit Core-Definitionen gemerged.
|
||||||
Zusätzliche Module (z.B. von Extensions):
|
|
||||||
- Jedes Modul hat eigene `Resources/metadata/` Struktur
|
|
||||||
- Module sind gekapselt und wiederverwendbar
|
|
||||||
|
|
||||||
### custom/scripts/
|
#### entityDefs/{Entity}.json
|
||||||
**PHP Scripts für Wartung und Verwaltung:**
|
Definiert Entitäten mit Feldern, Beziehungen, Indizes:
|
||||||
|
- `fields` - Feldtypen, Validierungen, Optionen
|
||||||
|
- `links` - Relationships (belongsTo, hasMany, hasOne)
|
||||||
|
- `collection` - Sortierung, Standard-Filter
|
||||||
|
- `indexes` - Datenbank-Performance-Optimierung
|
||||||
|
|
||||||
#### workflow_manager.php
|
**Wichtig bei Relationships:**
|
||||||
Zentrale Schnittstelle für Workflow-Verwaltung:
|
- Bei hasMany-Relationships **BEIDE Seiten** definieren
|
||||||
- **list** - Alle Workflows (BPM + Simple) auflisten
|
- `relationName` muss identisch sein
|
||||||
- **read** - Workflow-Details anzeigen
|
- `foreign` zeigt auf den Link-Namen der Gegenseite
|
||||||
- **import** - Workflow aus JSON importieren
|
- Fehlt eine Seite: "404 Link does not exist"-Fehler
|
||||||
- **export** - Workflow nach JSON exportieren
|
|
||||||
- **delete** - Workflow löschen
|
#### clientDefs/{Entity}.json
|
||||||
|
Frontend-Konfiguration für Entitäten:
|
||||||
|
- `views` - Custom Views (detail, list, edit)
|
||||||
|
- `controller` - Custom Controller-Logik
|
||||||
|
- `filterList` - Report-Filter (mit `__APPEND__`)
|
||||||
|
- `sidePanels` - Report-Panels
|
||||||
|
- `relationshipPanels` - Relationship-Panel-Konfiguration
|
||||||
|
|
||||||
|
#### layouts/{Entity}/{LayoutType}.json
|
||||||
|
UI-Layout-Definitionen:
|
||||||
|
- Arrays von Panels mit `label` und `rows`
|
||||||
|
- `rows` sind Arrays von Zellen mit `{"name": "fieldName"}`
|
||||||
|
- Layout-Typen: detail, list, edit, kanban, bottomPanelsDetail
|
||||||
|
|
||||||
|
#### formula/{Entity}.json
|
||||||
|
Formula-Scripts für Validierung und Berechnung:
|
||||||
|
- `beforeSaveApiScript` - Vor dem Speichern (ab v7.5+)
|
||||||
|
- `afterSaveScript` - Nach dem Speichern
|
||||||
|
- **NICHT in entityDefs ablegen!** (funktioniert nicht)
|
||||||
|
|
||||||
|
#### i18n/{Language}/{Entity}.json
|
||||||
|
Mehrsprachige Labels und Tooltips:
|
||||||
|
- `fields` - Feld-Labels
|
||||||
|
- `links` - Relationship-Labels (identisch mit fields!)
|
||||||
|
- `tooltips` - Hilfe-Texte für Felder
|
||||||
|
- `labels` - Sonstige UI-Texte
|
||||||
|
- `presetFilters` - Report-Filter-Labels
|
||||||
|
|
||||||
|
**KRITISCH:** en_US ist Fallback-Sprache und MUSS vollständig sein!
|
||||||
|
|
||||||
|
### custom/Espo/Custom/Classes/
|
||||||
|
|
||||||
|
Custom PHP-Klassen für erweiterte Logik:
|
||||||
|
|
||||||
|
#### FormulaFunctions/{GroupName}/{FunctionName}Type.php
|
||||||
|
Custom Formula-Funktionen:
|
||||||
|
- Namespace: `Espo\Custom\Classes\FormulaFunctions\{GroupName}`
|
||||||
|
- Muss `BaseFunction` erweitern
|
||||||
|
- Registrierung in `app/formula.json` erforderlich
|
||||||
|
|
||||||
|
**Beispiel:** IBAN-Validierung, Custom Berechnungen
|
||||||
|
|
||||||
|
## Frontend Customizations (client/custom/)
|
||||||
|
|
||||||
|
### client/custom/src/modules/
|
||||||
|
|
||||||
|
AMD JavaScript-Module für wiederverwendbare Logik:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
define('custom:modules/my-module', [], function () {
|
||||||
|
return {
|
||||||
|
myFunction: function(params) {
|
||||||
|
// Wiederverwendbare Logik
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verwendung:** `define('path/to/view', ['custom:modules/my-module'], function (MyModule) { ... })`
|
||||||
|
|
||||||
|
**Beispiel:** `rvg-calculator.js` - RVG-Gebührenberechnung
|
||||||
|
|
||||||
|
### client/custom/src/views/
|
||||||
|
|
||||||
|
Custom Backbone.js Views für Entity-spezifisches UI-Verhalten:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
define('custom:views/entity/fields/fieldname', ['views/fields/base'], function (Dep) {
|
||||||
|
return Dep.extend({
|
||||||
|
setup: function () {
|
||||||
|
Dep.prototype.setup.call(this);
|
||||||
|
this.listenTo(this.model, 'change:field1', this.onFieldChange);
|
||||||
|
this.listenTo(this.model, 'sync', this.onSync); // Initial load
|
||||||
|
},
|
||||||
|
onFieldChange: function () {
|
||||||
|
// Reaktive Logik
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtige Patterns:**
|
||||||
|
- `listenTo(model, 'sync', callback)` - Initial berechnung beim Laden
|
||||||
|
- `listenTo(model, 'change:field', callback)` - Reaktivität
|
||||||
|
- `calculating` Flag verhindert Rekursion bei `model.set()`
|
||||||
|
|
||||||
|
**Registrierung in entityDefs:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"fields": {
|
||||||
|
"fieldName": {
|
||||||
|
"type": "varchar",
|
||||||
|
"view": "custom:views/entity/fields/fieldname"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### client/custom/css/
|
||||||
|
|
||||||
|
Custom CSS-Stylesheets für UI-Anpassungen:
|
||||||
|
|
||||||
|
**Datei erstellen:** `client/custom/css/my-styles.css`
|
||||||
|
|
||||||
|
**Registrieren in** `custom/Espo/Custom/Resources/metadata/app/client.json`:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cssList": [
|
||||||
|
"__APPEND__",
|
||||||
|
"client/custom/css/my-styles.css"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**CSS-Targeting-Strategien:**
|
||||||
|
- Feld-spezifisch: `.cell[data-name="fieldName"]`
|
||||||
|
- Entity-spezifisch: `body[data-controller="EntityName"]`
|
||||||
|
- View-spezifisch: `.detail`, `.edit`, `.list`
|
||||||
|
- Label vs. Value: `.label-text` vs. `.numeric-text`
|
||||||
|
|
||||||
|
**Nach CSS-Änderungen:** Rebuild + Browser Hard Refresh (Ctrl+Shift+R)
|
||||||
|
|
||||||
|
### client/custom/modules/
|
||||||
|
|
||||||
|
Third-Party Extensions und zusätzliche Module:
|
||||||
|
- `advanced/` - Advanced Pack (Reports, Workflows, BPM)
|
||||||
|
- `link-button/` - Custom Link-Button Extension
|
||||||
|
- `crm/` - CRM-Erweiterungen
|
||||||
|
|
||||||
|
Diese werden meist von Extensions installiert und sollten nicht manuell bearbeitet werden.
|
||||||
|
|
||||||
|
## Scripts und Tools (custom/scripts/)
|
||||||
|
|
||||||
|
### check_and_rebuild.sh
|
||||||
|
|
||||||
|
**Zentrale Schnittstelle** für Validierung und Rebuild:
|
||||||
|
|
||||||
|
**Funktionen:**
|
||||||
|
- ✓ JSON-Syntax-Validierung aller `.json` Dateien
|
||||||
|
- ✓ Dateirechte-Prüfung (www-data:www-data)
|
||||||
|
- ✓ System-Checks (Cache, Logs)
|
||||||
|
- ✓ Automatischer Rebuild bei Fehlerfreiheit
|
||||||
|
- ✓ Fehler-Reporting mit Zeilennummern
|
||||||
|
|
||||||
**Verwendung:**
|
**Verwendung:**
|
||||||
```bash
|
```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
|
./custom/scripts/check_and_rebuild.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Nützliche Befehle
|
**Ausgabe:**
|
||||||
|
- ✓ Grün: Alles in Ordnung, Rebuild erfolgreich
|
||||||
|
- ⚠ Gelb: Warnungen, Rebuild wird trotzdem ausgeführt
|
||||||
|
- ✗ Rot: Fehler, Rebuild wird NICHT ausgeführt
|
||||||
|
|
||||||
|
**Dieses Script sollte IMMER verwendet werden** statt manueller Rebuild-Befehle!
|
||||||
|
|
||||||
|
### workflow_manager.php
|
||||||
|
|
||||||
|
Kommandozeilen-Tool für Workflow-Verwaltung. Details siehe `/README.md` Abschnitt "Workflow-Verwaltung".
|
||||||
|
|
||||||
|
## Workflows (custom/workflows/)
|
||||||
|
|
||||||
|
Versionierte Workflow-Definitionen als JSON:
|
||||||
|
- Simple Workflows (regel-basiert)
|
||||||
|
- BPM Flowcharts (BPMN 2.0)
|
||||||
|
|
||||||
|
**Format-Dokumentation:** `custom/workflows/README.md`
|
||||||
|
|
||||||
|
**Verwaltung:** Über `workflow_manager.php` (siehe `/README.md`)
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Entwicklungs-Workflow
|
||||||
|
|
||||||
|
1. **Backend-Änderungen** (Metadata, PHP):
|
||||||
|
- Dateien in `custom/Espo/Custom/` bearbeiten
|
||||||
|
- `./custom/scripts/check_and_rebuild.sh` ausführen
|
||||||
|
- Logs prüfen: `data/logs/espo-*.log`
|
||||||
|
|
||||||
|
2. **Frontend-Änderungen** (JS, CSS):
|
||||||
|
- Dateien in `client/custom/` erstellen/bearbeiten
|
||||||
|
- In `app/client.json` registrieren (CSS) oder in entityDefs referenzieren (Views)
|
||||||
|
- `./custom/scripts/check_and_rebuild.sh` ausführen
|
||||||
|
- Browser Hard Refresh (Ctrl+Shift+R)
|
||||||
|
|
||||||
|
3. **Workflows**:
|
||||||
|
- JSON in `custom/workflows/` erstellen
|
||||||
|
- Mit `workflow_manager.php import` einspielen
|
||||||
|
- Im Admin-Interface testen
|
||||||
|
|
||||||
|
### Versionskontrolle
|
||||||
|
|
||||||
|
**Git committen:**
|
||||||
|
- Alle JSON-Dateien in `custom/`
|
||||||
|
- Alle JavaScript/CSS-Dateien in `client/custom/`
|
||||||
|
- Alle Workflows in `custom/workflows/`
|
||||||
|
- Scripts in `custom/scripts/`
|
||||||
|
|
||||||
|
**Nicht committen:**
|
||||||
|
- `data/cache/` - Cache-Verzeichnis
|
||||||
|
- `data/logs/` - Log-Dateien
|
||||||
|
- `data/upload/` - Hochgeladene Dateien
|
||||||
|
|
||||||
|
### Dateirechte
|
||||||
|
|
||||||
|
Das `check_and_rebuild.sh` Script prüft automatisch Dateirechte. Falls manuelle Korrektur nötig:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Alle Workflows auflisten
|
sudo chown -R www-data:www-data custom/
|
||||||
docker exec espocrm php /var/www/html/custom/scripts/workflow_manager.php list
|
sudo find custom/ -type f -name "*.json" -exec chmod 664 {} \;
|
||||||
|
sudo find custom/ -type d -exec chmod 775 {} \;
|
||||||
# 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
|
### Naming Conventions
|
||||||
|
|
||||||
- **Hauptdokumentation:** `/README.md` - Vollständige KI-Dokumentation für EspoCRM
|
**Entities:** PascalCase mit Präfix (z.B. `CVmhMietverhltnis`, `CBeteiligte`)
|
||||||
|
|
||||||
|
**Links:** camelCase mit Präfix (z.B. `contactsMietverhltnis`, `vmhMieterbeteiligte`)
|
||||||
|
|
||||||
|
**relationName:** Kombination beider Entities (z.B. `cVmhMietverhltnisContact`)
|
||||||
|
|
||||||
|
**Workflows:** kebab-case mit Präfix (z.B. `vmh-erstberatung-abschliessen.json`)
|
||||||
|
|
||||||
|
**Views:** Entity-Pfad + Funktion (z.B. `custom:views/c-vmh-erstgespraech/fields/rvg-calculated`)
|
||||||
|
|
||||||
|
**CSS:** kebab-case mit Kontext (z.B. `erstgespraech-highlight.css`)
|
||||||
|
|
||||||
|
## Häufige Fehler und Lösungen
|
||||||
|
|
||||||
|
### "Link does not exist" (404)
|
||||||
|
**Ursache:** Unvollständige hasMany-Relationship
|
||||||
|
**Lösung:** Beide Seiten der Relationship in entityDefs definieren
|
||||||
|
|
||||||
|
### Tooltip zeigt nur Feldnamen
|
||||||
|
**Ursache:** Fehlerhafte oder fehlende `en_US` i18n-Datei
|
||||||
|
**Lösung:** Tooltips in ALLEN Sprachen definieren (en_US ist Fallback!)
|
||||||
|
|
||||||
|
### Formula-Script wird nicht ausgeführt
|
||||||
|
**Ursache:** Script in `entityDefs` statt `formula/`
|
||||||
|
**Lösung:** Separate `formula/{Entity}.json` Datei erstellen
|
||||||
|
|
||||||
|
### CSS-Änderungen nicht sichtbar
|
||||||
|
**Ursache:** Browser-Cache oder fehlende Registrierung
|
||||||
|
**Lösung:** In `app/client.json` registrieren + Rebuild + Hard Refresh
|
||||||
|
|
||||||
|
### "Permission denied" bei Layout-Bearbeitung
|
||||||
|
**Ursache:** Falsche Dateirechte (root statt www-data)
|
||||||
|
**Lösung:** `./custom/scripts/check_and_rebuild.sh` führt automatisch Rechteprüfung durch
|
||||||
|
|
||||||
|
## Weiterführende Dokumentation
|
||||||
|
|
||||||
|
- **Hauptdokumentation:** `/README.md` - Workflow-Management, Formula-Scripts, Reports, Troubleshooting
|
||||||
- **Workflow-Formate:** `/custom/workflows/README.md` - JSON-Format-Spezifikationen
|
- **Workflow-Formate:** `/custom/workflows/README.md` - JSON-Format-Spezifikationen
|
||||||
- **EspoCRM Docs:** https://docs.espocrm.com
|
- **EspoCRM Docs:** https://docs.espocrm.com
|
||||||
|
|||||||
@@ -349,8 +349,8 @@ return [
|
|||||||
0 => 'youtube.com',
|
0 => 'youtube.com',
|
||||||
1 => 'google.com'
|
1 => 'google.com'
|
||||||
],
|
],
|
||||||
'cacheTimestamp' => 1769200199,
|
'cacheTimestamp' => 1769201197,
|
||||||
'microtime' => 1769200199.876961,
|
'microtime' => 1769201197.484917,
|
||||||
'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