| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client2/arni-solutions.de/web/crm/ |
Upload File : |
# ArNi Solutions CRM
Schlankes, professionelles CRM mit Schwerpunkt **Rechnungserstellung** (Rechnungen
auch **ohne** vorher angelegten Kunden möglich), Kunden-, Produkt- und Ticketverwaltung,
wiederkehrenden Rechnungen, PDF-Erzeugung (TCPDF) und SMTP-Mailversand (PHPMailer).
Reines PHP 7.3 (kein Framework), MySQL/MariaDB, **alle Assets lokal** (Bootstrap,
FontAwesome, Roboto-Webfont, PHPMailer) – **keine CDN-Abhängigkeiten**.
---
## 1. Voraussetzungen
- PHP **7.3+** mit Extensions: `pdo_mysql`, `mbstring`, `gd` (Logo/PDF), `openssl`, `fileinfo`
- MySQL / MariaDB
- TCPDF (auf diesem Server bereits unter `/var/www/arni-solutions.de/web/tcpdf` vorhanden;
Pfad in `config/config.php` → `paths.tcpdf` einstellbar)
- Webserver (Apache/Nginx). **DocumentRoot sollte auf `crm/public` zeigen.**
## 2. Installation
1. Projekt liegt unter `/var/www/arni-solutions.de/web/crm`.
2. Konfiguration anlegen (falls noch nicht vorhanden):
```
cp config/config.local.php.example config/config.local.php
```
Darin DB-Zugang, App-Key und Cron-Token eintragen. (Auf diesem Server bereits gesetzt.)
3. Aufruf im Browser:
- Empfohlen: DocumentRoot = `…/crm/public` → `https://arni-solutions.de/`
- Ohne eigene vHost-Anpassung erreichbar unter `https://arni-solutions.de/crm/public/`
(eine `index.php` im CRM-Stamm leitet von `…/crm/` nach `…/crm/public/` weiter).
## 3. Datenbank importieren
```
mysql -u <user> -p <datenbank> < database/schema.sql
mysql -u <user> -p <datenbank> < database/schema_modules.sql # Zusatzmodule
mysql -u <user> -p <datenbank> < database/schema_affiliate.sql # Affiliate/ADCELL
mysql -u <user> -p <datenbank> < database/seed.sql
```
> Alle Tabellen sind mit `crm_` präfixiert und können daher gefahrlos in einer
> bereits genutzten Datenbank liegen.
## 4. Rechte für storage
Der Webserver-Benutzer muss in `storage/` und `public/uploads/` schreiben können:
```
chmod -R 775 storage public/uploads
# ggf. Eigentümer setzen, z.B.:
# chown -R www-data:www-data storage public/uploads
```
Enthält: `storage/invoices` (PDFs), `storage/logs` (App-/Mail-/PHP-Logs), `storage/uploads`.
## 5. SMTP einrichten
Im CRM unter **Einstellungen → SMTP**: Host, Port, Verschlüsselung (STARTTLS/SSL/keine),
Benutzer, Passwort, Absender. Darunter **Testmail** zum Prüfen. Jeder Versand wird in
`crm_mail_logs` protokolliert.
## 6. Cronjob für wiederkehrende Rechnungen
Datei: `public/cron/recurring_invoices.php` (durch ein Token geschützt – siehe
`config/config.local.php` → `cron.token`).
Beispiel (täglich 06:00 Uhr) per CLI:
```
0 6 * * * /usr/bin/php /var/www/arni-solutions.de/web/crm/public/cron/recurring_invoices.php token=DEIN_CRON_TOKEN >> /var/www/arni-solutions.de/web/crm/storage/logs/cron.log 2>&1
```
oder per HTTP:
```
0 6 * * * curl -s "https://arni-solutions.de/crm/public/cron/recurring_invoices.php?token=DEIN_CRON_TOKEN"
```
Fällige Vorgänge können auch manuell über **Wiederk. Rechnungen → „Fällige ausführen"**
gestartet werden. Erzeugte Rechnungen werden in `crm_cron_logs` und `storage/logs/cron.log`
protokolliert. Je nach Einstellung als **Entwurf** oder (bei „Auto-Versand") direkt als
offene Rechnung inkl. E-Mail.
**Weitere Cronjobs** (gleiches Token):
```
# Erinnerungen versenden (z.B. alle 5 Minuten)
*/5 * * * * /usr/bin/php /var/www/arni-solutions.de/web/crm/public/cron/reminders.php token=DEIN_CRON_TOKEN
# Webseiten online/offline prüfen (z.B. alle 10 Minuten)
*/10 * * * * /usr/bin/php /var/www/arni-solutions.de/web/crm/public/cron/website_check.php token=DEIN_CRON_TOKEN
```
## 6b. Pushover & Erinnerungen
Unter **Einstellungen → Benachrichtigungen** Pushover *API-Token* und *User-Key*
(von pushover.net) eintragen und mit „Pushover-Testnachricht" prüfen. Erinnerungen
(Modul **Erinnerungen**) werden zum gewählten Zeitpunkt per Pushover und/oder E-Mail
versendet (Cron `reminders.php`). Der Webseiten-Checker meldet Statuswechsel
(online↔offline) ebenfalls per Pushover.
## 6c. Dokumentation per CLI/KI importieren
`cli/doc_import.php` (nur Kommandozeile) legt Projekte/Dokumente an bzw. erzeugt neue
**Versionen** – ideal für Scripte und KI-Ausgaben:
```
php cli/doc_import.php --project="Webshop" --title="Deployment" --file=deploy.md --note="Update"
./build.sh | php cli/doc_import.php --project="Webshop" --title="Build-Log"
php cli/doc_import.php --project="Webshop" --title="Setup" --file=setup.md --attach=setup.sh --ai
```
Existiert ein Dokument mit gleichem Titel im Projekt, wird automatisch eine neue Version
committet (Versionshistorie wie bei GitHub). `--attach` hängt eine Datei an (mit
Code-Vorschau in der Oberfläche).
## 7. Login (aus seed.sql)
```
E-Mail: admin@arni-solutions.de
Passwort: admin1234
```
> **Bitte nach dem ersten Login ändern** (Benutzer → bearbeiten). Rollen: `admin`,
> `office`, `support`.
## 8. Hinweise für PHP 7.3
- Der Code ist bewusst 7.3-kompatibel (keine Arrow-Functions, kein `match`,
keine typed properties, kein Nullsafe-Operator).
- Die auf dem Server vorhandene TCPDF-Version erzeugt einige PHP-Warnungen; die
PDF-Erzeugung schaltet die Anzeige dieser Warnungen gezielt ab (`app/Pdf.php`),
damit der PDF-Stream sauber bleibt.
- Für den Produktivbetrieb in `config/config.local.php` `app.debug = false` setzen.
---
## Affiliate (ADCELL)
Neuer Bereich **Affiliate** mit Dashboard, Partnerprogrammen, Werbemitteln,
Statistiken (aktueller Monat als Standard), Synchronisation und Einstellungen.
Nur für eingeloggte **Admins**. Tabellen mit Prefix `crm_affiliate_*`.
**ADCELL-Einstellungen** (Affiliate → Einstellungen): Die ADCELL-API v2
(`https://api.adcell.org/api/v2`) nutzt ein **Token-Verfahren**. Benötigt werden nur
**API Base-URL**, **Account-ID** (= `userName`/`userId`, im Feld Publisher-ID) und das
**API-Passwort** (in ADCELL: *Mein ADCELL → Einstellungen → API*; der API-Zugang ist nur
über den Hauptaccount erreichbar). Intern holt das CRM damit über `/user/getToken` ein
Token (≈15 Min, gecached) und hängt es an jeden Request. **API-Secret wird nicht benötigt**
(liegt im aufklappbaren Bereich „Erweiterte Authentifizierung" für andere Netzwerke).
Secrets werden **maskiert** und nie ausgegeben; leeres Feld = unverändert. Dazu
Sync-Intervall, Aktiv-Schalter, „Verbindung testen" (ruft `/user/whoami`) und „Manuelle Synchronisation".
**API-Konfiguration** (`config/adcell.php`): echte Endpunkte sind hinterlegt –
`/affiliate/program/export` (Programme), `/affiliate/promotion/getPromotionCount` +
`getPromotionType{Banner,Text,Html,Rss,Csv}` (Werbemittel je Typ),
`/affiliate/statistic/byDay|byProgram|byPromotion` (Statistiken) und
`/affiliate/dashboard/getQuickInfo` (Kontoübersicht). Antwort unter `data.items`
(paginiert, `rows`/`page`). Anpassbar sind außerdem Rate-Limit, Antwortformat und das
**Feld-Mapping** (`'unsere_spalte' => 'ADCELL-Feld'`) je Entität. Statistik-Speicherung
ohne Doppelzählung: Konto-Tageswerte (byDay), je Programm (byProgram), je Werbemittel (byPromotion).
**Fallback-Import (CSV/XML/JSON)**: Falls keine API erreichbar ist, unter
Affiliate → Synchronisation eine Datei hochladen (Datenart Programme/Werbemittel/
Statistiken wählen). Das Feld-Mapping aus `config/adcell.php` greift auch hier
(CSV-Header bzw. JSON/XML-Schlüssel = Quellfelder). Zusätzlich gibt es
**„Demo-Daten importieren"** (Beispielprogramme/-werbemittel + Statistiken für den
aktuellen Monat) zum sofortigen Ausprobieren – Beispieldatei: `database/affiliate_demo.json`.
**Cronjob** (Token wie die übrigen Crons aus `config/config.local.php`):
```
*/30 * * * * /usr/bin/php /var/www/arni-solutions.de/web/crm/public/cron/adcell_sync.php --token=DEIN_CRON_TOKEN
```
Synchronisiert Programme, Werbemittel und die Statistiken des aktuellen Monats; optional
`--what=programs|creatives|statistics|all`. Alle Läufe werden in `crm_affiliate_sync_logs`
protokolliert (ohne Secrets).
**Wichtig bei großen Accounts:** „Alles synchronisieren" im Browser kann lange dauern und
ein **504-Timeout** des Webservers/Proxys auslösen (die Synchronisation läuft serverseitig
trotzdem weiter, da `ignore_user_abort`). Lang laufende Aktionen geben den **Session-Lock
sofort frei** (`session_write_close`), sodass man eingeloggt bleibt und die Oberfläche nicht
blockiert. Für große Accounts daher den **Cron** nutzen (kein Proxy-Timeout) oder die
Werbemittel/Programme/Statistiken einzeln synchronisieren.
**Statistiken**: Standard ist der aktuelle Monat; Zeitraumfilter, Gruppierung nach
Partnerprogramm und Werbemittel, Tageswerte und CSV-Export. Speicher-Konvention:
Summen/Verlauf/Top-Programme nutzen Programm-Tageszeilen (creative_id = NULL),
Top-Werbemittel die Werbemittel-Zeilen.
**Bekannte Einschränkung:** Die echten ADCELL-Endpunkte und Feldnamen hängen vom
Publisher-Account/der API-Berechtigung ab und müssen mit den Zugangsdaten aus dem
ADCELL-Publisher-Account in `config/adcell.php` abgeglichen werden. Ohne gültige API
funktionieren Demo- und Datei-Import vollständig; API-Fehler werden sauber gemeldet
und geloggt (keine Fatal Errors).
## Projektstruktur
```
config/ Konfiguration (config.php + config.local.php mit Secrets)
app/
controllers/ Controller (Auth, Dashboard, Invoice, Customer, Product, Ticket,
Recurring, MailTemplate, Setting, User)
models/ Models (BaseModel + Entitäten)
views/ Templates (layouts, partials, je Modul)
helpers/ Globale Hilfsfunktionen
lib/PHPMailer/ PHPMailer (lokal, kein CDN)
Database.php Pdf.php Mailer.php RecurringRunner.php Controller.php CrmTcpdf.php
public/ Webroot: index.php (Front-Controller), assets/, uploads/, cron/
storage/ invoices/ (PDF), logs/, uploads/
templates/mail/ (Platz für Mailvorlagen-Dateien)
database/ schema.sql, seed.sql
```
## Funktionsumfang
- **Rechnungen**: Kunde optional **oder** freie Rechnungsadresse; Positionen aus dem
Produktkatalog **oder** frei (Menge, Einzelpreis, Rabatt %, MwSt-Satz je Position,
Drag&Drop-Sortierung); automatische Netto-/MwSt-/Brutto-Berechnung; Status
Entwurf/Offen/Bezahlt/Überfällig/Storniert; **PDF** (Logo, Firmendaten, MwSt-
Aufschlüsselung, Zahlungsinfo); **E-Mail-Versand** mit PDF-Anhang; Zahlungen
erfassen; Duplizieren; Stornieren; CSV-Export; Such-/Status-/Zeitraum-/Kundenfilter.
Wird eine Rechnung mit freier Adresse (ohne Kunde) erstellt, schlägt das System auf
der Rechnungsseite vor, daraus einen **Kunden anzulegen** (Ja/Nein) – bzw. einen
bereits vorhandenen passenden Kunden zu **verknüpfen**.
- **Nummernkreis**: Präfix, optional Jahr, Auffüll-Stellen, Startnummer, Vorschau;
atomare Vergabe (keine Doppelnummern).
- **Kunden / Produkte / Tickets / Benutzer**: vollständige Verwaltung inkl. Filter.
- **Mail-Templates** mit Platzhaltern, Standard-Template, Status-Regel,
Kunden-spezifischem Template (am Kunden hinterlegt) und Vorschau.
- **Wiederkehrende Rechnungen** inkl. Cron.
- **Erinnerungen + Pushover**: zeitgesteuerte Benachrichtigungen per Pushover/E-Mail.
- **Webseitenverwaltung** mit Online/Offline-Checker (Verlauf, Antwortzeit, Pushover
bei Statuswechsel, Cron).
- **Projekt-Dokumentation** mit Versionierung (wie GitHub), Datei-Anhängen,
Code-Vorschau und CLI/KI-Import.
- **Prompt-Vorlagen** (für Bilder/Web) mit Kategorien, Tags, Live-Suche, Favoriten und
Platzhalter-Ausfüllung.
- **Sicherheit**: Session-Login, Passwort-Hashing (bcrypt), CSRF bei allen Formularen,
ausschließlich Prepared Statements, Output-Escaping, Upload-Validierung,
Rollen, Logging.