Files
espocrm/custom/CUSTOM_DIRECTORY.md
bsiggel 9f069d1fe2 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.
2026-01-23 21:46:38 +01:00

344 lines
13 KiB
Markdown

# 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