# EspoCRM Custom Directory - Vollständige Übersicht 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/ # Backend Customizations ├── Espo/ │ ├── Custom/ # Custom Entitäten, Services, Controller │ │ ├── Classes/ # Custom PHP-Klassen │ │ │ └── FormulaFunctions/ # Custom Formula-Funktionen │ │ ├── Controllers/ # Custom Controller │ │ ├── Services/ # Custom Services │ │ ├── Repositories/ # Custom Repositories │ │ └── Resources/ │ │ ├── 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 ``` ## Backend Customizations (custom/Espo/) ### custom/Espo/Custom/Resources/metadata/ Dies ist das Herzstück der EspoCRM-Customization. Alle JSON-Dateien hier werden rekursiv mit Core-Definitionen gemerged. #### entityDefs/{Entity}.json Definiert Entitäten mit Feldern, Beziehungen, Indizes: - `fields` - Feldtypen, Validierungen, Optionen - `links` - Relationships (belongsTo, hasMany, hasOne) - `collection` - Sortierung, Standard-Filter - `indexes` - Datenbank-Performance-Optimierung **Wichtig bei Relationships:** - Bei hasMany-Relationships **BEIDE Seiten** definieren - `relationName` muss identisch sein - `foreign` zeigt auf den Link-Namen der Gegenseite - Fehlt eine Seite: "404 Link does not exist"-Fehler #### 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:** ```bash ./custom/scripts/check_and_rebuild.sh ``` **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 sudo chown -R www-data:www-data custom/ sudo find custom/ -type f -name "*.json" -exec chmod 664 {} \; sudo find custom/ -type d -exec chmod 775 {} \; ``` ### Naming Conventions **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 - **EspoCRM Docs:** https://docs.espocrm.com