# FINN.ghost Systemhandbuch

Alles über Systemvoraussetzungen, Installation und Konfiguration von FINN.ghost

# Überblick

FINN.ghost verbindet die SelectLine Warenwirtschaft mit Drittsystemen — Webshops,
Portalen, Rechnungsdiensten — und bringt eigene Module wie FINN.lager mit. Dieses Handbuch
beschreibt die Anwendung selbst: Installation, Einstellungen und Betrieb. Die einzelnen
Module haben jeweils ein eigenes Handbuch.

![Aufbau einer FINN.ghost-Installation](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-ueberblick-9efead05-ueberblick-aufbau.png)

## Wie FINN.ghost arbeitet

| Eigenschaft | Bedeutung im Betrieb |
| ------------------------------------ | ------------------------------------------- |
| läuft als **Windows-Dienst** | startet mit dem Server, niemand muss sich anmelden |
| bedient wird es im **Browser** | vom Server oder von jedem Rechner im Netz, auch vom Tablet |
| **keine eigene Datenbank** nötig | was gespeichert werden muss, legt FINN.ghost selbst ab |
| nutzt die **SelectLine-REST-API** | schreibende Zugriffe gehen durch die SelectLine, nicht daran vorbei |
| liest zusätzlich **direkt per SQL** | für Massenabfragen, weil das deutlich schneller ist |

<p class="callout info">Die Oberfläche lässt sich auch in den SelectLine-Dashboards anzeigen. Dann arbeiten die Anwender in der SelectLine und sehen dort dieselben Masken.</p>

## Die zwei Zugriffswege auf die SelectLine

Das ist der Punkt, an dem die meisten Rückfragen entstehen — deshalb gleich vorweg:

| Weg | Wofür | Was er braucht |
| ------------------ | ---------------------------------- | ------------------------------ |
| **SelectLine-API** | alles Schreibende: Belege, Adressen, Artikel, Journale | API-Lizenz und einen API-Benutzer |
| **MSSQL direkt** | Lesen und Massenabfragen | einen SQL-Benutzer mit Rechten auf die Mandantendatenbank |

<p class="callout warning">Beide Zugänge werden gebraucht. Fehlt einer, läuft die Anwendung nicht oder nur halb — und die Meldung dazu steht dann im Protokoll, nicht in der Oberfläche.</p>

Siehe [Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank) und [SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api).

## Was die Lizenz steuert

Welche Module im Menü erscheinen, entscheidet die Lizenz. Ohne Lizenz für ein Modul gibt es
dafür weder Menüpunkt noch Zeitsteuerung.

Siehe [Lizenz und Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/lizenz-und-module).

## Aufbau dieses Handbuchs

| Kapitel | Inhalt |
| -------------------------------------- | ----------------------------------------- |
| [Installation](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/system-und-installationsvoraussetzungen) | Voraussetzungen, Setup, Update, erste Schritte |
| [Einstellungen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-einstellungen) | Datenbank, API, Lizenz, Server, E-Mail, OSS |
| [Zertifikate und SSL](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt) | Let's Encrypt, Zertifikat einrichten und erstellen |
| [Laufender Betrieb](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein) | Zeitsteuerung, Protokoll, Makros, config.json, Wartung |
| [Einstellungen ohne Maske](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/grundlagen) | Einstellungen, die es nur in der `config.json` gibt |

## Handbücher der Module

| Modul | Handbuch |
| ------------------------------ | ------------------------------------------------- |
| Shopware 6 | [FINN.ghost für Shopware6](https://wiki.dako-it.com/books/finnghost-fur-shopware6-wHZ) |
| Shopify | [FINN.ghost für Shopify](https://wiki.dako-it.com/books/finnghost-fur-shopify) |
| FINN.webshop | [FINN.ghost für FINN.webshop](https://wiki.dako-it.com/books/finnghost-fur-finnwebshop-0s8) |
| FINN.lager | [FINN.lager Handbuch](https://wiki.dako-it.com/books/finnlager-handbuch) |
| Merkmale und Varianten | [FINN.ghost für Merkmale und Varianten](https://wiki.dako-it.com/books/finnghost-fur-merkmale-und-varianten) |
| FINN.mail2SL | [FINN.mail2SL Handbuch](https://wiki.dako-it.com/books/finnmail2sl-handbuch) |
| GetMyInvoices | [FINN.GMI Handbuch](https://wiki.dako-it.com/books/finngmi-handbuch) |
| FINN.AI MCP | [FINN.AI MCP für SelectLine](https://wiki.dako-it.com/books/finnai-mcp-fur-selectline) |

Was sich von Version zu Version geändert hat, steht im
[Änderungsverlauf](https://wiki.dako-it.com/books/finnghost-anderungsverlauf).

# Installation

Voraussetzungen, Setup, Update und die ersten Schritte nach der Installation.

# System- und Installationsvoraussetzungen

Diese Seite ist die Checkliste vor dem Termin. Was hier fehlt, hält die Installation auf.

## Systemvoraussetzungen

| Was | Anforderung |
| ------------------------- | ---------------------------------------------------- |
| **Betriebssystem** | Windows Server oder Windows, auf dem ein Dienst laufen darf |
| **SelectLine Warenwirtschaft** | NEO ab Version 25.x |
| **SelectLine-API** | aktive API-Lizenz für den AppKey **FINN.ghost** |
| **MSSQL** | Zugriff auf die Datenbank des Mandanten |
| **sl.mobile** | installiert und erreichbar, weil die API dazugehört |

<p class="callout info">Bei der Lizenz <strong>SelectLine Shopify-Anbindung</strong> ist die API bereits enthalten — ein eigener AppKey wird dort nicht gebraucht.</p>

<p class="callout warning">Ist die SelectLine älter als Version 25, bitte vorher mit DAKO-IT abstimmen. Es kann gehen, ist aber kein Regelfall.</p>

## Was vor der Installation bereitliegen muss

| Angabe | Wozu |
| ---------------------------------------- | ------------------------------------------ |
| **SQL-Benutzer** mit Rechten auf die Mandantendatenbank | direkter Lesezugriff, Anlegen eigener Tabellen |
| **Windows-Administratorkennwort** | der Dienst wird installiert und gestartet |
| **URL des SelectLine-Servers und von sl.mobile** | daraus ergibt sich die API-Adresse |
| **SelectLine-Benutzer** mit Rechten auf den Mandanten und die API | der Zugang, mit dem FINN.ghost schreibt |
| **Lizenzschlüssel** für FINN.ghost | schaltet die Module frei |
| **Zugang zum Server** per RDP oder TeamViewer | für die Einrichtung durch DAKO-IT |

<p class="callout danger">Der SQL-Benutzer braucht das Recht, <strong>Tabellen anzulegen</strong> — FINN.ghost legt eigene Tabellen im Mandanten an. Ein Benutzer mit reinem Leserecht genügt nicht. Üblich ist <code>sa</code>; ein eigener Benutzer mit denselben Rechten auf diese eine Datenbank ist die sauberere Lösung.</p>

## Ports

| Port | Wofür | Anmerkung |
| ------- | -------------------------------- | ------------------------------------- |
| **8083** | Oberfläche von FINN.ghost | Standard, in den Einstellungen änderbar |
| 1433 | MSSQL | oder der Port der Instanz |
| 443 | SelectLine-API und Drittsysteme | ausgehend |

<p class="callout info">Sollen mehrere FINN.ghost-Installationen auf einem Server laufen, braucht jede einen eigenen Port.</p>

Siehe [Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache).

## Rechte des SelectLine-Benutzers

Der API-Benutzer arbeitet in der SelectLine wie ein Anwender — mit seinen Rechten.

<p class="callout warning">Fehlt ihm ein Recht, scheitert genau die Übertragung, die es braucht. Ein Beispiel aus der Praxis: ohne <strong>Leserecht auf Mitarbeiter</strong> ließ sich der Dienst früher nicht starten. Solche Fälle werden inzwischen abgefangen und protokolliert, gelöst sind sie damit aber nicht — das Recht fehlt weiterhin.</p>

## Nächster Schritt

[Installation und Update](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/installation-und-update)

# Installation und Update

## Setup herunterladen

| Stand | Adresse |
| ------------------- | ---------------------------------------------- |
| **aktuelle Version** | <https://dako-it.com/ghost/latest.php> |
| Testversion | <https://dako-it.com/ghost/downloadTest/> |
| ältere Versionen | <https://dako-it.com/ghost/download/> |

<p class="callout info">Die Testversion ist für abgesprochene Fälle gedacht — etwa wenn eine Korrektur vor dem nächsten regulären Stand gebraucht wird. Im Regelbetrieb gehört die aktuelle Version installiert.</p>

## Installation

Die Datei heißt `SelectLine.ghost Setup <Version>.exe`. Der Ablauf:

1. Setup starten und die **Lizenzvereinbarung** bestätigen.
2. **Installationsordner** wählen. Vorgeschlagen wird `C:\DAKO\SelectLine.ghost`.
3. Installieren lassen — Dienst und Programmdateien werden eingerichtet.
4. **Öffne SelectLine.ghost im Browser** anhaken und **Fertigstellen**.

![Installationsordner wählen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-installation-fee08d51-installation-ordner.png)

<p class="callout danger">Der <strong>Ordnername</strong> ist keine Nebensache: Aus ihm entstehen der Name des Windows-Dienstes und die Bezeichnung im Browser-Reiter. Bei mehreren Installationen auf einem Server unterscheidet man sie daran — dann gehören sprechende Ordnernamen gewählt, etwa <code>SelectLine.ghost.Shop</code> und <code>SelectLine.ghost.Lager</code>.</p>

![Installation abschließen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-installation-5ddd0bc5-installation-fertigstellen.png)

Der Browser öffnet danach die Einstellungen unter `https://localhost:8083`. Dort geht es
weiter mit [Erste Schritte](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/erste-schritte).

## Der Windows-Dienst

Das Setup richtet den Dienst ein und startet ihn. Er heißt **`SL_<Ordnername>`**.

| Aufgabe | Weg |
| ---------------------------- | ---------------------------------------------- |
| Dienst neu starten | Windows-Dienste, Eintrag `SL_<Ordnername>` |
| Status prüfen | derselbe Eintrag |
| Startart | automatisch, der Dienst läuft ohne Anmeldung |

<p class="callout info">Bei Installationen aus älteren Versionen heißt der Dienst noch ohne das Präfix <code>SL_</code>. Das Setup kommt mit beiden Varianten zurecht und räumt die alte auf.</p>

<p class="callout warning">Ein Neustart des Dienstes bricht laufende Übertragungen ab. Vorher in der Zeitsteuerung nachsehen, ob gerade eine Aufgabe läuft.</p>

Siehe [Zeitsteuerung der Module (allgemein)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).

## Update

### Welche Version läuft

Die Version steht in der **Fußzeile** der Oberfläche.

![Version in der Fußzeile](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-installation-109868e9-installation-version.png)

Auf der Startseite stehen Neuigkeiten und der Änderungsverlauf, und dort wird auch angezeigt,
wenn eine neuere Version bereitliegt.

![Startseite mit Hinweis auf ein Update](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-installation-f68722a5-installation-startseite.png)

<p class="callout info">Die Version von FINN.ghost sollte zur eingesetzten SelectLine-Version passen. Nach einem SelectLine-Update gehört deshalb auch FINN.ghost aktualisiert.</p>

### Update per Tastenkombination

Ab Version 23.1.6.240831 genügt in der Oberfläche:

**Strg + Alt + U**

Das Update läuft vollständig im Hintergrund — herunterladen, Dienst anhalten, austauschen,
starten.

<p class="callout success">Das ist der empfohlene Weg. Er braucht keinen Dateizugriff auf den Server und wählt automatisch den richtigen Ordner.</p>

### Update von Hand

Bei älteren Versionen oder wenn die Tastenkombination nicht greift: Setup herunterladen und
wie bei der Installation ausführen — **mit demselben Installationsordner**.

![Denselben Ordner bestätigen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-installation-37ce4294-installation-ordner-bestaetigen.png)

<p class="callout danger">Ein anderer Ordner ergibt eine <strong>zweite, leere Installation</strong> mit eigenem Dienst und eigener Konfiguration — nicht ein Update. Der vorgeschlagene Ordner ist nicht zwangsläufig der bestehende; er gehört geprüft.</p>

Die Konfiguration bleibt erhalten: `config.json` wird beim Update nicht überschrieben. Siehe
[Anpassungen über die config.json](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/anpassungen-uber-die-configjson).

### Nach dem Update prüfen

- Lässt sich die Oberfläche im Browser öffnen?
- Steht in der Fußzeile die neue Version?
- Läuft die Zeitsteuerung wieder — steht bei den Aufgaben eine nächste Ausführung?

## Deinstallation

Das Setup bringt keinen Deinstallationseintrag mit. Zum Entfernen:

1. Windows-Dienst `SL_<Ordnername>` anhalten und entfernen.
2. Installationsordner löschen.

<p class="callout warning">Im Installationsordner liegt die <code>config.json</code> mit der gesamten Konfiguration — inklusive der verschlüsselten Kennwörter. Vor dem Löschen eine Kopie sichern, falls die Installation später wieder gebraucht wird.</p>

<p class="callout info">Die von FINN.ghost angelegten Tabellen im SelectLine-Mandanten bleiben dabei stehen. Sie stören den Betrieb der SelectLine nicht.</p>

## Nächster Schritt

[Erste Schritte](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/erste-schritte)

# Erste Schritte

Nach der Installation ist FINN.ghost leer. Diese Reihenfolge führt zur ersten
funktionierenden Verbindung — sie ergibt sich aus der Oberfläche selbst: Erst wenn die
Datenbank steht, erscheint die API-Karte, und erst mit der API die Lizenz.

![Oberfläche nach der Installation](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-erste-schritte-49d84f36-oberflaeche-start.png)

## Die Reihenfolge

| Schritt | Wo | Ergebnis |
| ------- | ------------------------------ | ------------------------------------ |
| 1 | [Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank) | Verbindung zur Mandantendatenbank |
| 2 | [SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api) | Anmeldung an der SelectLine |
| 3 | [Lizenz und Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/lizenz-und-module) | die gekauften Module erscheinen im Menü |
| 4 | [Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache) | Port, Bildformat, Anmeldung |
| 5 | [SSL mit Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt) | Aufruf ohne Sicherheitswarnung |
| 6 | [E-Mail-Versand](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-versand) | Fehlermeldungen kommen per Mail an |
| 7 | Modulhandbuch | die Einrichtung des jeweiligen Moduls |

<p class="callout info">Die Karten der Einstellungen erscheinen der Reihe nach: ohne Datenbankverbindung keine API-Karte, ohne API keine Lizenzkarte, ohne Lizenz keine Modulkarten. Wenn eine Karte fehlt, ist der Schritt davor noch nicht fertig.</p>

## Zu den Einstellungen

Über das Menü **SelectLine → Einstellungen**.

![Menü SelectLine, Einstellungen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-erste-schritte-8aa34880-menue-einstellungen.png)

Siehe [SelectLine - Einstellungen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-einstellungen).

## Woran man sieht, dass es läuft

| Prüfung | Wo |
| ----------------------------------------- | ------------------------------ |
| Der Mandantenname erscheint in der API-Karte | Einstellungen, Karte *API* |
| Die lizenzierten Module stehen im Menü | linke Navigation |
| Im Protokoll steht `Server initialisiert!` | [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen) |
| Die Zeitsteuerung nennt eine nächste Ausführung | [Zeitsteuerung](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein) |

<p class="callout success">Der Mandantenname in der API-Karte ist die aussagekräftigste Einzelprüfung: Er kommt aus der SelectLine selbst. Steht er dort, sind API-Adresse, Benutzer, Kennwort und Lizenz in Ordnung.</p>

## Bevor die Module eingerichtet werden

<p class="callout danger">FINN.ghost schreibt über die SelectLine-API in einen <strong>echten Mandanten</strong> — es legt Belege an, bucht Bestände und ändert Artikel. Beim Einrichten deshalb erst prüfen, auf welchen Mandanten die Datenbankverbindung zeigt, und für Versuche einen Testmandanten verwenden.</p>

## Nächster Schritt

[SelectLine - Einstellungen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-einstellungen)

# Einstellungen

Datenbank, SelectLine-API, Lizenz, Server, E-Mail-Versand und EU-Auslands-Kontengruppen.

# SelectLine - Einstellungen

Unter **SelectLine → Einstellungen** liegen alle Angaben, mit denen sich FINN.ghost in Ihre
Datenstruktur einfügt. Jede Karte hat hier eine eigene Seite.

![Menü SelectLine, Einstellungen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-einstellungen-8aa34880-menue-einstellungen.png)

## Die Karten

| Karte | Inhalt |
| ------------------------------- | ------------------------------------------------- |
| [Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank) | Verbindung zur MSSQL-Datenbank des Mandanten |
| [SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api) | Adresse, AppKey und Benutzer der SelectLine-API |
| [Lizenz und Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/lizenz-und-module) | der Lizenzschlüssel und was er freischaltet |
| [Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache) | Port, Bildformat, Bildqualität, Benutzeranmeldung |
| [SSL mit Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt) | Zertifikat automatisch beantragen und erneuern |
| [E-Mail-Versand](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-versand) | SMTP für Fehlermeldungen |
| [E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365) | OAuth und App-Only statt Kennwort |
| [EU-Auslands-Kontengruppen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/eu-auslands-kontengruppen) | Kontengruppen je Land für das OSS-Verfahren |

<p class="callout info">Die Karten erscheinen nacheinander: ohne Datenbankverbindung keine API-Karte, ohne API keine Lizenz, ohne Lizenz keine Modulkarten. Eine fehlende Karte heißt also, dass der Schritt davor noch offen ist.</p>

## Wann die Anwendung neu startet

Manche Änderungen wirken erst nach einem Neustart des Dienstes — den löst FINN.ghost selbst
aus:

| Geändert | Was passiert |
| -------------------------------- | ------------------------------------------ |
| Lizenz | Neustart, damit die Module geladen werden |
| Port, Bildformat, Anmeldung | Neustart, danach ist die Oberfläche unter dem neuen Port erreichbar |
| Zertifikat geholt oder importiert | Neustart, damit es der Webserver verwendet |
| Datenbank, API, E-Mail | kein Neustart |

<p class="callout warning">Wird der Port geändert, ist die Oberfläche unter der alten Adresse nicht mehr erreichbar. Der Browser wird auf die neue Adresse geschickt — Lesezeichen und Verknüpfungen gehören danach angepasst.</p>

## Wo die Angaben landen

In der `config.json` im Installationsordner. Felder mit Kennwörtern werden dabei
verschlüsselt. Siehe [Anpassungen über die config.json](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/anpassungen-uber-die-configjson).

## Nächster Schritt

[Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank)

# Datenbank

Die Verbindung zur MSSQL-Datenbank des SelectLine-Mandanten. Sie ist die erste Einstellung —
ohne sie erscheinen die weiteren Karten nicht.

![Karte Datenbank](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-datenbank-7173c8cd-einstellungen-datenbank.png)

## Die Felder

| Feld | Inhalt | Beispiel |
| ------------- | ------------------------------------------- | ------------------------ |
| **Name** | Datenbank des gewünschten Mandanten | `SL_M1000` |
| **Host** | SQL-Server und Instanz | `SQL02\SQLSRV17` |
| **Nutzer** | SQL-Benutzer | `sa` |
| **Passwort** | dessen Kennwort | |

<p class="callout danger">Der Benutzer braucht Rechte auf die Tabellen dieser Datenbank <strong>und</strong> das Recht, Tabellen anzulegen — FINN.ghost legt eigene Tabellen im Mandanten an. Ein reines Leserecht genügt nicht.</p>

<p class="callout info">Der Datenbankname bestimmt, in <strong>welchem Mandanten</strong> gearbeitet wird. Bei mehreren Mandanten lohnt der doppelte Blick: Alles, was FINN.ghost später schreibt, landet in diesem.</p>

## Wozu der direkte Zugriff dient

Gelesen wird direkt aus der Datenbank, geschrieben über die SelectLine-API.

<p class="callout success">Der Grund ist Tempo: Ein Artikelexport prüft zehntausende Datensätze auf Änderungen. Über die API wäre das um ein Vielfaches langsamer. Geschäftslogik — Nummernkreise, Preisfindung, Buchungen — bleibt trotzdem der SelectLine überlassen.</p>

Siehe [SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api).

## Wenn die Verbindung nicht zustande kommt

| Meldung oder Symptom | Ursache |
| ---------------------------------------- | ------------------------------------ |
| Anmeldung fehlgeschlagen | Benutzer oder Kennwort falsch |
| Server nicht erreichbar | Instanzname falsch, oder der SQL-Browser-Dienst läuft nicht |
| Zeitüberschreibung | Firewall zwischen FINN.ghost und SQL-Server |
| Verbindung steht, Module bleiben leer | falsche Datenbank — ein anderer Mandant |

<p class="callout info">Bei einer benannten Instanz muss der Dienst <strong>SQL Server Browser</strong> laufen, sonst lässt sich <code>Server\Instanz</code> nicht auflösen. Alternativ den Port direkt angeben.</p>

Die genaue Meldung steht im Protokoll. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api)

# SelectLine-API

Über die SelectLine-API schreibt FINN.ghost in den Mandanten — Belege, Adressen, Artikel,
Journale, Buchungen. Sie gehört zu sl.mobile.

![Karte API](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-api-22254d3d-einstellungen-api.png)

## Die Felder

| Feld | Inhalt |
| ------------- | ---------------------------------------------------------- |
| **URL** | Adresse der API |
| **AppKey** | der bei SelectLine hinterlegte AppKey |
| **Nutzer** | in der SelectLine angelegter API-Benutzer |
| **Passwort** | dessen Kennwort |

### URL

Die Adresse von sl.mobile, mit `slmobileApi` statt `slmobile`:

```text
https://localhost/slmobileApi
```

<p class="callout info">Läuft FINN.ghost auf demselben Server wie sl.mobile, ist <code>localhost</code> die zuverlässigste Angabe — sie ist unabhängig von Rechnernamen und DNS.</p>

### AppKey

Der AppKey wurde beim Kauf der API bei SelectLine angegeben. Einzusehen in der SelectLine
unter **Hilfe → Lizenzierung → AppKeys**.

<p class="callout warning">Weicht der Eintrag hier vom AppKey in der SelectLine ab, meldet die API die Anmeldung ab. In diesem Fall den Wert aus der SelectLine übernehmen — nicht umgekehrt.</p>

<p class="callout info">Bei der Lizenz <strong>SelectLine Shopify-Anbindung</strong> ist die API in der Lizenz enthalten; das Feld bleibt dann leer. In der Oberfläche steht deshalb <em>für Shopify nicht notwendig</em>.</p>

### Nutzer und Passwort

Der in der API-Konfiguration von sl.mobile eingerichtete API-Benutzer.

<p class="callout danger">Dieser Benutzer arbeitet mit seinen SelectLine-Rechten. Er braucht Rechte auf den Mandanten und auf die Bereiche, die die eingesetzten Module berühren — Artikel, Adressen, Belege, Journale. Fehlt ein Recht, scheitert genau die Übertragung, die es braucht.</p>

## Ob die Verbindung steht

Steht sie, zeigt die Karte oben rechts den **Namen des Mandanten**. Ein Klick darauf öffnet
die Angaben zum angemeldeten Benutzer.

<p class="callout success">Das ist die verlässlichste Einzelprüfung der Einrichtung: Der Name kommt aus der SelectLine — er erscheint nur, wenn Adresse, Benutzer, Kennwort und API-Lizenz zusammenpassen.</p>

## Wenn die Anmeldung scheitert

| Symptom | Ursache |
| ------------------------------------------- | ----------------------------------- |
| kein Mandantenname, Fehler im Protokoll | Benutzer, Kennwort oder AppKey falsch |
| Adresse nicht erreichbar | sl.mobile läuft nicht, oder die URL zeigt auf `slmobile` statt `slmobileApi` |
| Zertifikatsfehler | das Zertifikat von sl.mobile wird nicht anerkannt |
| Anmeldung geht, Schreiben scheitert | dem SelectLine-Benutzer fehlen Rechte |

Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[Lizenz und Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/lizenz-und-module)

# Lizenz und Module

Die Lizenz entscheidet, welche Module FINN.ghost lädt. Was nicht lizenziert ist, erscheint
nicht — weder im Menü noch in der Zeitsteuerung.

![Karte Lizenz](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-lizenz-944a3fc2-einstellungen-lizenz.png)

## Der Schlüssel

Ein Feld, in das der Lizenzschlüssel eingetragen wird. Er kommt vom Fachhändler oder von
DAKO-IT.

<p class="callout info">Nach dem Speichern startet die Anwendung neu, damit die freigeschalteten Module geladen werden. Das dauert einige Sekunden; danach die Seite neu laden.</p>

## Was danach im Menü steht

Je Modul ein Menüpunkt.

![Menü mit den lizenzierten Modulen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-lizenz-21bd9e67-menue-module.png)

| Modul | Was es macht |
| ---------------------------- | -------------------------------------------- |
| **Shopware6** | Anbindung an Shopware 6 |
| **Shopify** | Anbindung an Shopify |
| **FINN.webshop \| B2B** | eigener Webshop |
| **FINN.lager** | Lagermodul mit Boards und Kommissionierung |
| **Merkmale / Varianten** | Sachmerkmale pflegen, Varianten erzeugen |
| **FINN.mail2sl** | E-Mails automatisch als Journal ablegen |
| **GetMyInvoices** | Eingangsrechnungen aus dem Portal |
| **FINN.AI MCP** | Zugriff für KI-Anwendungen |
| **Pipedrive** | Abgleich mit dem CRM |
| **Übersetzungen** | Artikeltexte übersetzen |

<p class="callout info">Zu jedem Modul gibt es ein eigenes Handbuch. Die Liste steht im Überblick.</p>

Siehe [Überblick](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/uberblick).

## Wenn ein Modul fehlt

| Prüfung | |
| ------------------------------------------------ | ------------------------ |
| Ist der Schlüssel vollständig eingetragen? | Karte *Lizenz* |
| Wurde nach dem Speichern neu gestartet? | Seite neu laden |
| Ist das Modul überhaupt lizenziert? | beim Fachhändler erfragen |
| Steht im Protokoll ein Fehler zur Lizenz? | [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen) |

<p class="callout warning">Die Lizenz wird gegen einen Dienst von DAKO-IT geprüft. Ohne ausgehende Internetverbindung kann diese Prüfung fehlschlagen — dann fehlen die Module, obwohl der Schlüssel richtig ist.</p>

## Nächster Schritt

[Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache)

# Server und Oberfläche

Die Karte **FINN.ghost** regelt, unter welchem Port die Oberfläche läuft, wie Bilder an die
Drittsysteme übertragen werden und ob eine Anmeldung nötig ist.

![Einstellungen Server](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-server-5a6862dd-einstellungen-server.png)

## Port

Der Port, unter dem die Oberfläche erreichbar ist. Standard ist **8083**.

<p class="callout warning">Laufen mehrere FINN.ghost-Installationen auf einem Server, braucht jede einen eigenen Port. Sonst startet die zweite nicht — im Protokoll steht dann, dass der Port belegt ist.</p>

<p class="callout info">Nach dem Speichern startet die Anwendung neu und der Browser wird auf die neue Adresse geschickt. Lesezeichen, Verknüpfungen und die Einbindung in die SelectLine-Dashboards gehören danach angepasst.</p>

## Bildformat

In welchem Format Bilder aus der SelectLine an das angeschlossene System übertragen werden —
unabhängig davon, wie sie in der SelectLine abgelegt sind.

| Wert | Wann |
| ------------ | -------------------------------------------------- |
| **webp** | moderne Shops; kleinste Dateien bei gleicher Qualität |
| **jpg** | breiteste Verträglichkeit, für Fotos |
| **png** | wenn Transparenz gebraucht wird |
| **original** | keine Umwandlung; überträgt, was in der SelectLine liegt |

<p class="callout info">Umgewandelt wird beim Übertragen. Eine Änderung wirkt deshalb erst auf Bilder, die danach übertragen werden — für die bereits übertragenen braucht es einen Lauf, der die Bilder erneut schickt.</p>

## Bildqualität

Ein Wert von 1 bis 100, Vorgabe **80**. Gilt für die verlustbehafteten Formate.

<p class="callout success">80 ist ein bewusst gewählter Kompromiss: Unterschiede zum Original sind im Shop kaum zu sehen, die Dateien aber deutlich kleiner. Höhere Werte lohnen selten, niedrigere werden bei Produktbildern sichtbar.</p>

<p class="callout info">Bei <em>original</em> hat die Angabe keine Wirkung.</p>

## Nutzeranmeldung

Ist der Haken gesetzt, verlangt die Oberfläche eine Anmeldung. Angemeldet wird sich mit den
**API-Benutzern aus sl.mobile**.

<p class="callout danger">Ohne diesen Haken kann jeder, der den Server im Netz erreicht, die Oberfläche öffnen — und damit Einstellungen ändern und Übertragungen starten. Für jede Installation, die über <code>localhost</code> hinaus erreichbar ist, gehört die Anmeldung eingeschaltet.</p>

<p class="callout warning">Vor dem Einschalten prüfen, dass ein passender API-Benutzer existiert und das Kennwort bekannt ist — sonst sperrt man sich aus. Wieder hinein kommt man dann nur über die <code>config.json</code> auf dem Server.</p>

Siehe [Anpassungen über die config.json](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/anpassungen-uber-die-configjson).

## Zertifikate herunterladen

Zwei Schaltflächen in derselben Karte:

| Schaltfläche | Was sie liefert |
| ----------------------------- | ------------------------------------------- |
| **ROOT ZERTIFIKAT DOWNLOAD** | das Stammzertifikat für den Arbeitsplatz |
| **ZERTIFIKATE DOWNLOAD** | Zertifikat und Schlüssel für diese Installation |

Das ist der ältere Weg zu einer sicheren Verbindung. Siehe
[Zertifikat einrichten](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zertifikat-einrichten).

<p class="callout success">Für Installationen mit einer öffentlich erreichbaren Domain ist Let's Encrypt einfacher — dort entfällt das Verteilen von Zertifikaten an die Arbeitsplätze.</p>

Siehe [SSL mit Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt).

## Nächster Schritt

[SSL mit Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt)

# E-Mail-Versand

FINN.ghost verschickt Fehlermeldungen und Zusammenfassungen per E-Mail. Der Versand ist
technisch optional — praktisch ist er das Frühwarnsystem der Installation.

![Einstellungen Mail](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-mail-f94d6c89-einstellungen-mail.png)

<p class="callout success">Ohne Mailversand merkt niemand, dass eine Übertragung seit Tagen scheitert — die Meldung steht nur im Protokoll, und dort sieht niemand von selbst hinein. Diese Karte gehört deshalb zur Grundeinrichtung.</p>

## Ein- und ausschalten

Der Schalter in der Kartenüberschrift. Ausgeschaltet werden keine Mails verschickt und die
Felder sind ausgeblendet.

## Drei Wege

Die Karte hat drei Reiter:

| Reiter | Wann |
| ------------------- | -------------------------------------------------- |
| **Standard** | ein SMTP-Konto mit Benutzer und Kennwort |
| **M365-OAuth** | Microsoft 365, Versand über ein angemeldetes Konto |
| **M365-App-Only** | Microsoft 365, Versand ohne Benutzeranmeldung |

Die beiden Microsoft-Wege stehen auf einer eigenen Seite. Siehe
[E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365).

## Reiter Standard

| Feld | Inhalt |
| ------------------------------ | ------------------------------------------- |
| **Host** | SMTP-Server des Kontos |
| **Port** | üblich 465 (SSL) oder 587 (STARTTLS) |
| **Verschlüsselte Verbindung** | Verschlüsselung einschalten |
| **Outlook365** | Besonderheiten von Microsoft-365-Postfächern |
| **Nutzer**, **Passwort** | Zugang zum Postfach |
| **Absender** | abweichende Absenderadresse |
| **Absender Name** | Anzeigename |
| **Empfänger** | Ziele, mehrere mit Komma getrennt |
| **Betreff** | Betreff der Meldungsmails |
| **Interval** | Zeitspanne in Minuten |

<p class="callout info">Beim Speichern wird sofort eine <strong>Testmail</strong> verschickt. Kommt sie nicht an, stimmt etwas an den Angaben — dann lohnt der Blick ins Protokoll, dort steht die Antwort des Mailservers.</p>

## Was das Intervall bedeutet

Meldungen werden gesammelt und im eingestellten Abstand verschickt — nicht einzeln.

<p class="callout success">Das ist Absicht: Bei einer Störung entstehen viele gleichartige Fehler. Gesammelt ergibt das eine Mail, einzeln hunderte.</p>

<p class="callout info">10 Minuten sind ein guter Startwert. Wer nur die Tagesübersicht braucht, kann höher gehen; unter 5 Minuten wird es unruhig.</p>

## Ein sinnvoller Betreff

Der Betreff steht in jeder Mail. Bei mehreren Installationen gehört hinein, um **welche** es
sich handelt — etwa `FINN.ghost Shop` und `FINN.ghost Lager`.

<p class="callout warning">Sonst sind die Mails nicht auseinanderzuhalten, sobald der zweite Ghost dazukommt.</p>

## Wenn keine Mails ankommen

| Ursache | Abhilfe |
| ------------------------------------------ | ----------------------------------- |
| Schalter aus | einschalten |
| Empfänger leer | Adresse eintragen |
| Anmeldung abgelehnt | Kennwort prüfen; bei Microsoft 365 einen der M365-Reiter nutzen |
| Port blockiert | Firewall für ausgehendes SMTP öffnen |
| Mails im Spam | Absenderadresse zur eigenen Domain passend wählen |

<p class="callout warning">Microsoft hat die Anmeldung per Benutzer und Kennwort für SMTP abgeschaltet. Für Microsoft 365 führt der Reiter <em>Standard</em> deshalb in der Regel nicht mehr zum Ziel.</p>

Siehe [E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365).

## Nächster Schritt

[E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365)

# E-Mail über Microsoft 365

Microsoft hat die Anmeldung mit Benutzer und Kennwort für SMTP abgeschaltet. Für Postfächer
in Microsoft 365 führt deshalb einer der beiden folgenden Wege zum Ziel. Beide brauchen
einmalig eine **App-Registrierung** im Azure-Portal.

## Welchen Weg wählen

| | **OAuth** | **App-Only** |
| ------------------- | ------------------------------ | ------------------------------ |
| Versand als | ein angemeldetes Benutzerkonto | die Anwendung selbst |
| Anmeldung | einmalig im Browser | keine |
| Absender | das angemeldete Postfach | ein frei angegebenes Postfach |
| Nötige Rechte | Delegiert: `SMTP.Send`, `offline_access` | Anwendung: `Mail.Send` |

<p class="callout success">Für einen Server, der jahrelang unbeaufsichtigt läuft, ist <strong>App-Only</strong> der robustere Weg: Es hängt kein Benutzerkonto daran, das gesperrt werden oder das Kennwort wechseln könnte.</p>

<p class="callout danger">App-Only mit <code>Mail.Send</code> als Anwendungsberechtigung erlaubt der Registrierung, als <strong>jedes</strong> Postfach der Organisation zu senden. Wer das eng ziehen will, beschränkt die Registrierung in Exchange Online über eine Anwendungszugriffsrichtlinie auf das eine Absenderpostfach. Das gehört mit der Microsoft-365-Administration abgestimmt.</p>

## Weg 1 — OAuth

![Reiter M365-OAuth](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-e933b566-m365-oauth-1-tab.png)

### 1. App registrieren

Im Azure-Portal eine neue App-Registrierung anlegen, mit einem eindeutigen Namen. Als
**Umleitungs-URI** wird die Adresse dieser FINN.ghost-Installation eingetragen, endend auf
`/api/mail/oauth/redirect`:

```text
https://finn.kunde.de:8083/api/mail/oauth/redirect
```

![App-Registrierung anlegen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-a925f20d-m365-oauth-2-appregistrierung.png)

<p class="callout danger">Die Umleitungs-URI muss <strong>zeichengenau</strong> mit der Adresse übereinstimmen, unter der FINN.ghost erreichbar ist — samt Port. Weicht sie ab, bricht Microsoft die Anmeldung mit einer Meldung zur Redirect-URI ab. Das ist der häufigste Stolperstein.</p>

<p class="callout warning">In älteren Fassungen dieser Anleitung endete die Adresse auf <code>/api/settings/oauth/redirect</code>. Das gilt nicht mehr — der Pfad lautet <code>/api/mail/oauth/redirect</code>.</p>

### 2. Clientschlüssel erstellen

Unter **Zertifikate & Geheimnisse** einen neuen Clientschlüssel anlegen und den **Wert**
sofort notieren.

![Clientschlüssel erstellen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-72f97cbd-m365-oauth-3-clientschluessel.png)

<p class="callout warning">Der Wert wird nur einmal angezeigt. Wer ihn nicht notiert, muss einen neuen Schlüssel anlegen. Clientschlüssel laufen außerdem ab — das Ablaufdatum gehört notiert, sonst bleibt der Mailversand irgendwann ohne Vorwarnung stehen.</p>

### 3. Berechtigungen setzen

Unter **API-Berechtigungen** zwei delegierte Berechtigungen von **Microsoft Graph**
hinzufügen und die Zustimmung erteilen:

| Berechtigung | Wofür |
| ---------------- | -------------------------------------------- |
| `SMTP.Send` | Mails über SMTP AUTH senden |
| `offline_access` | Zugriff behalten, ohne erneute Anmeldung |

![API-Berechtigungen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-3bed4cd7-m365-oauth-4-berechtigungen.png)

<p class="callout info"><code>User.Read</code> steht dort in der Regel schon — es wird beim Anlegen der Registrierung mitgegeben und kann bleiben. Wichtig ist der grüne Haken bei <em>Status</em>: ohne erteilte Zustimmung greifen die Berechtigungen nicht.</p>

### 4. Werte übertragen

Aus dem Reiter **Übersicht** der Registrierung:

| Feld in Azure | Feld in FINN.ghost |
| ------------------------------- | ------------------ |
| Anwendungs-ID (Client) | **Client ID** |
| Verzeichnis-ID (Mandant) | **Tenant ID** |
| beim Anlegen hinterlegte Umleitungs-URI | **Redirect URI** |
| notierter Wert des Clientschlüssels | **Client Secret** |

![Werte in FINN.ghost eintragen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-0737a4b9-m365-oauth-5-felder.png)

### 5. Verbinden

Nach dem Klick auf **Verbinden** fragt Microsoft nach der Anmeldung. Danach steht die
Verbindung, und in der Karte erscheint die Adresse des verbundenen Kontos.

<p class="callout info">Angemeldet wird das Postfach, aus dem gesendet wird. Es muss ein Postfach in derselben Organisation sein.</p>

## Weg 2 — App-Only

![Reiter M365-App-Only](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-07385ff4-m365-apponly-1-tab.png)

### 1. App registrieren

Wie oben eine neue App-Registrierung mit eindeutigem Namen. Eine Umleitungs-URI wird hier
**nicht** gebraucht.

![App-Registrierung anlegen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-2e774cfd-m365-apponly-2-appregistrierung.png)

### 2. Clientschlüssel erstellen

Unter **Zertifikate & Geheimnisse**, Wert notieren.

![Clientschlüssel erstellen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-97ff022d-m365-apponly-3-clientschluessel.png)

### 3. Berechtigung setzen

Unter **API-Berechtigungen** eine **Anwendungsberechtigung** von Microsoft Graph hinzufügen
und die Zustimmung erteilen:

| Berechtigung | Typ |
| ------------ | ------------------------ |
| `Mail.Send` | Anwendung |

![API-Berechtigung Mail.Send](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-eef69e85-m365-apponly-4-berechtigungen.png)

<p class="callout warning">Anwendungsberechtigungen brauchen immer die <strong>Administratorzustimmung</strong>. Ohne sie schlägt der Versand mit einer Rechtemeldung fehl, obwohl alle Werte richtig eingetragen sind.</p>

### 4. Werte übertragen

| Feld in Azure | Feld in FINN.ghost |
| ------------------------ | ------------------- |
| Anwendungs-ID (Client) | **Client ID** |
| Verzeichnis-ID (Mandant) | **Tenant ID** |
| Wert des Clientschlüssels | **Client Secret** |
| — | **Absender-E-Mail** |

![Werte in FINN.ghost eintragen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-m365-65dfcf5d-m365-apponly-5-felder.png)

Die **Absender-E-Mail** ist das Postfach, aus dem gesendet wird.

<p class="callout info">Nach dem Speichern verschickt FINN.ghost eine Testmail an die eingetragenen Empfänger und bestätigt das in der Karte. Kommt sie nicht an, fehlt meist die Administratorzustimmung.</p>

Über **Trennen** wird die Verbindung wieder gelöst.

## Wenn der Versand nicht geht

| Meldung oder Symptom | Ursache |
| -------------------------------------------- | ----------------------------------- |
| Fehler zur Redirect-URI beim Verbinden | Umleitungs-URI weicht ab |
| Anmeldung geht, Versand scheitert | Berechtigung fehlt oder ohne Zustimmung |
| lief monatelang, jetzt nicht mehr | Clientschlüssel abgelaufen |
| App-Only meldet fehlende Rechte | Administratorzustimmung nicht erteilt |
| Absender wird abgelehnt | Postfach gehört nicht zur Organisation |

Die Antwort von Microsoft steht im Protokoll. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[EU-Auslands-Kontengruppen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/eu-auslands-kontengruppen)

# EU-Auslands-Kontengruppen

Beim Import von Bestellungen aus einem Shop entscheidet die **Kontengruppe** des Kunden,
mit welchen Erlöskonten gebucht wird. Für Lieferungen in andere EU-Länder ist das je Land
unterschiedlich — das ist das **OSS-Verfahren**.

![Einstellungen OSS](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-oss-e680a00a-einstellungen-oss.png)


## Was eingestellt wird

Je Land eine Zeile:

| Spalte | Inhalt |
| --------------------------- | ------------------------------------------- |
| **Land (ISO)** | Länderkennzeichen mit zwei Zeichen, etwa `AT` |
| **Kontengruppe ohne VAT** | für Kunden ohne gültige Umsatzsteuer-Identnummer |
| **Kontengruppe mit VAT** | für Kunden mit gültiger Umsatzsteuer-Identnummer |

Hinzugefügt wird ein Land über das Feld **Land hinzufügen (ISO2)**; die Kontengruppen kommen
aus der Auswahl der im Mandanten vorhandenen Gruppen.

<p class="callout info">Es gibt zusätzlich eine <strong>Vorgabe</strong> für alle Länder ohne eigene Zeile. Damit genügt es, die Länder einzutragen, die abweichend behandelt werden.</p>

## Welche Adresse zählt

Maßgeblich ist das Land der **Lieferadresse** der Bestellung, nicht das der Rechnungsadresse.

<p class="callout success">Das entspricht dem OSS-Verfahren: Besteuert wird dort, wo die Ware ankommt.</p>

## Wann es wirkt

Beim Anlegen oder Aktualisieren eines Kunden im Rahmen des Bestellimports. Bestehende Kunden
und bereits importierte Bestellungen werden nicht nachträglich geändert.

<p class="callout warning">Diese Einstellung gehört <strong>vor</strong> dem ersten Bestellimport gesetzt. Sonst liegen die ersten Bestellungen mit der falschen Kontengruppe im Mandanten und müssen von Hand korrigiert werden.</p>

## Wer das entscheidet

<p class="callout danger">Welche Kontengruppe für welches Land richtig ist, ist eine steuerliche Frage. Sie gehört mit der Buchhaltung oder dem Steuerberater geklärt — nicht in der Schnittstelle geraten.</p>

## Zurück zur Übersicht

[SelectLine - Einstellungen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-einstellungen)

# Zertifikate und SSL

Zertifikate von Let's Encrypt, Zertifikat einrichten und Zertifikate selbst erstellen.

# SSL mit Let's Encrypt

FINN.ghost kann sein Zertifikat selbst bei Let's Encrypt beantragen und automatisch
erneuern. Das ist der empfohlene Weg — er ersetzt das Erstellen und Verteilen eigener
Zertifikate.

![Einstellungen SSL](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-letsencrypt-a8adeb2c-einstellungen-ssl.png)

## Warum das die einfachere Lösung ist

| | eigenes Zertifikat | Let's Encrypt |
| ------------------------- | -------------------------------- | ------------------------- |
| Am Arbeitsplatz | Stammzertifikat installieren, je Rechner | nichts zu tun |
| Gültigkeit | von Hand erneuern | erneuert sich selbst |
| Vom Browser anerkannt | erst nach Installation | sofort |
| Voraussetzung | keine | eine öffentliche Domain |

<p class="callout success">Der entscheidende Unterschied liegt beim Anwender: Ein selbst erstelltes Zertifikat muss auf jedem Rechner installiert werden, der die Oberfläche aufruft — und auf jedem neuen wieder. Mit Let's Encrypt entfällt das vollständig.</p>

## Voraussetzungen

| | |
| ------------------------------- | -------------------------------------------- |
| **Lizenzmodul SSL** | ohne dieses Modul lässt sich der Schalter nicht setzen |
| **Eine Domain** | etwa `finn.kunde.de` |
| **Zugriff auf das DNS der Domain** | für einen einmaligen CNAME-Eintrag |
| **Ausgehende Internetverbindung** | für den Abruf des Zertifikats |

<p class="callout success">FINN.ghost muss dafür <strong>nicht</strong> aus dem Internet erreichbar sein. Der Nachweis läuft über einen DNS-Eintrag, nicht über eine eingehende Verbindung — es muss also kein Port ins Internet geöffnet werden.</p>

## Einrichten

### 1. Domain und E-Mail eintragen

| Feld | Inhalt |
| ---------- | ------------------------------------------------- |
| **Domain** | die öffentliche Domain, unter der FINN.ghost erreichbar sein soll |
| **E-Mail** | Kontaktadresse für Let's Encrypt |

<p class="callout info">Die Domain muss auf die Installation zeigen, damit der Aufruf im Browser funktioniert — für die Ausstellung des Zertifikats selbst genügt der CNAME aus Schritt 2.</p>

### 2. Registrieren

Die Schaltfläche **Registrieren** meldet die Installation einmalig an. Danach zeigt die Karte
einen **CNAME-Eintrag**, der im öffentlichen DNS der Domain angelegt werden muss:

```text
_acme-challenge.finn.kunde.de.  CNAME  <von FINN.ghost angezeigter Wert>.
```

<p class="callout danger">Dieser Eintrag ist der Kern des Verfahrens: Über ihn weist FINN.ghost bei jeder Ausstellung nach, dass es zur Domain gehört. Er muss <strong>dauerhaft</strong> bestehen bleiben — wird er gelöscht, scheitert die nächste Erneuerung.</p>

<p class="callout info">Angelegt wird er einmal. Danach ist am DNS nichts mehr zu tun, auch nicht bei jeder Erneuerung.</p>

### 3. Zertifikat anfordern

**Zertifikat anfordern** holt das Zertifikat. Anschließend startet die Anwendung neu, damit
der Webserver es verwendet.

Danach zeigt die Karte, bis wann es gültig ist und wie viele Tage bleiben.

<p class="callout warning">Der Vorgang dauert bis zu zwei Minuten — der DNS-Eintrag muss sich erst verbreiten. Solange bitte nichts erneut anklicken.</p>

## Test-Modus

Der Haken **Test-Modus (Staging)** arbeitet gegen die Übungsumgebung von Let's Encrypt.

<p class="callout success">Sinnvoll beim Einrichten: Let's Encrypt begrenzt die Zahl der Ausstellungen je Domain und Woche. In der Übungsumgebung gilt diese Grenze nicht — Fehlversuche kosten dort nichts.</p>

<p class="callout danger">Ein Zertifikat aus dem Test-Modus wird von <strong>keinem</strong> Browser anerkannt. Nach dem erfolgreichen Test den Haken entfernen und das Zertifikat erneut anfordern.</p>

## Mehrere Installationen, eine Domain

**Exportieren** erzeugt einen Code, der auf einer weiteren FINN.ghost-Installation unter
**Importieren** eingefügt wird. Die zweite Installation übernimmt damit Domain und Zugang,
holt sich ihr Zertifikat selbst und startet neu.

<p class="callout success">Damit braucht der CNAME-Eintrag nur einmal angelegt zu werden, auch wenn mehrere Installationen dieselbe Domain nutzen.</p>

<p class="callout danger">Der Exportcode enthält den Zugang zur Zertifikatsverwaltung dieser Domain. Er gehört nicht in eine E-Mail an Dritte und nicht in ein Ticketsystem.</p>

## Erneuerung

Läuft von selbst:

| | |
| ------------------------ | ------------------------------------------ |
| Prüfung | alle 12 Stunden, Aufgabe *SSL Zertifikat erneuern* |
| Erneuert wird | wenn weniger als 30 Tage Restlaufzeit bleiben |
| Zusätzlich | bei jedem Start der Anwendung |

<p class="callout info">Nach einer Erneuerung startet die Anwendung neu, damit das neue Zertifikat verwendet wird. Das dauert wenige Sekunden und fällt im Betrieb kaum auf — laufende Übertragungen brechen dabei aber ab.</p>

Siehe [Zeitsteuerung der Module (allgemein)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).

## Wo die Dateien liegen

Im Installationsordner unter `data\ssl`:

| Datei | Inhalt |
| ------------------- | ---------------------------- |
| `server.cert` | das Zertifikat |
| `server.key` | der zugehörige Schlüssel |
| `acme-account.key` | der Zugang zu Let's Encrypt |

<p class="callout warning">Diese Dateien gehören in die Datensicherung des Servers — und ansonsten in keine fremden Hände.</p>

## Wenn es nicht klappt

| Symptom | Ursache |
| ------------------------------------------ | ---------------------------------- |
| Schalter lässt sich nicht setzen | Lizenzmodul SSL fehlt |
| Meldung, es sei nicht vollständig konfiguriert | Domain, E-Mail oder Registrierung fehlt |
| Ausstellung bricht ab | CNAME nicht angelegt oder noch nicht verbreitet |
| Browser warnt weiter | Test-Modus noch aktiv, oder die Domain wird nicht aufgerufen |
| lief, jetzt abgelaufen | CNAME wurde entfernt, oder keine Internetverbindung |

<p class="callout info">Wird die Oberfläche über <code>localhost</code> oder eine IP-Adresse aufgerufen, warnt der Browser trotz gültigem Zertifikat — es gilt für die Domain. Der Aufruf muss über die Domain gehen.</p>

Die Meldungen stehen im Protokoll. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[Zertifikat einrichten](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zertifikat-einrichten)

# Zertifikat einrichten

Der Weg ohne öffentliche Domain: ein von DAKO-IT ausgestelltes Zertifikat in der Installation
hinterlegen und das Stammzertifikat an den Arbeitsplätzen installieren.

<p class="callout success">Ist die Installation unter einer öffentlichen Domain erreichbar, ist Let's Encrypt der einfachere Weg — dann entfällt dieser Abschnitt vollständig, weil an den Arbeitsplätzen nichts zu tun ist.</p>

Siehe [SSL mit Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt).

## Voraussetzung

Die Oberfläche muss über den **Rechnernamen** aufgerufen werden, nicht über die IP-Adresse:

```text
https://ihrghostserver:8083
```

<p class="callout danger">Ein Zertifikat gilt für einen Namen. Beim Aufruf über die IP-Adresse warnt der Browser weiter, auch wenn alles richtig eingerichtet ist.</p>

## Schritt 1 — Zertifikat in der Installation hinterlegen

Unter **SelectLine → Einstellungen → FINN.ghost**.

![Schaltflächen zum Download der Zertifikate](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-28f9b5b4-zertifikat-download.png)

1. **ZERTIFIKATE DOWNLOAD** — lädt `cert.zip` herunter.
2. Archiv entpacken. Darin liegen `server.cert` und `server.key`.
3. Beide Dateien in den Ordner `data\ssl` der Installation legen und die vorhandenen
   überschreiben:

```text
C:\DAKO\SelectLine.ghost\data\ssl
```

4. Den Windows-Dienst `SL_<Ordnername>` neu starten.

<p class="callout info">Der Pfad richtet sich nach dem gewählten Installationsordner. Wurde ein anderer Ordner verwendet, liegt <code>data\ssl</code> entsprechend dort.</p>

<p class="callout warning">Ohne Neustart des Dienstes bleibt das alte Zertifikat in Verwendung — die Dateien werden nur beim Start gelesen.</p>

## Schritt 2 — Stammzertifikat am Arbeitsplatz installieren

Über **ROOT ZERTIFIKAT DOWNLOAD** die Datei `RootCA.crt` herunterladen. Wie sie installiert
wird, hängt vom Browser ab.

<p class="callout warning">Dieser Schritt ist an <strong>jedem</strong> Rechner nötig, der die Oberfläche aufruft — auch an jedem neuen. Das ist der Aufwand, den Let's Encrypt erspart.</p>

### Firefox

Firefox verwaltet Zertifikate in seinen eigenen Einstellungen.

![Zertifikatsverwaltung in Firefox](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-1015e3d7-zertifikat-firefox-einstellungen.png)

Dort `RootCA.crt` **importieren**.

![Import in Firefox](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-99a3e7a9-zertifikat-firefox-import.png)

### Chrome, Edge und andere

Diese Browser nutzen die Zertifikatsverwaltung von Windows. Ein Doppelklick auf
`RootCA.crt` startet die Installation.

![Zertifikat installieren](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-c0797665-zertifikat-windows-doppelklick.png)

Im Assistenten den passenden Speicher wählen und die folgenden Dialoge bestätigen.

![Speicher auswählen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-ab7dc201-zertifikat-windows-speicher.png)

![Bestätigen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zertifikat-einrichten-e3d850af-zertifikat-windows-bestaetigen.png)

<p class="callout info">Anschließend den Browser vollständig schließen und neu öffnen. Solange ein Fenster offen bleibt, gilt oft noch die alte Bewertung.</p>

## Wenn der Browser weiter warnt

| Ursache | Abhilfe |
| ------------------------------------------ | ------------------------------------ |
| Aufruf über IP-Adresse | über den Rechnernamen aufrufen |
| Dienst nicht neu gestartet | Dienst neu starten |
| Stammzertifikat am Arbeitsplatz fehlt | Schritt 2 dort ausführen |
| Firefox statt Windows-Speicher | in Firefox gesondert importieren |
| Zertifikat abgelaufen | neu herunterladen und Schritt 1 wiederholen |

## Nächster Schritt

[Zertifikat erstellen (optional)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zertifikat-erstellen-optional)

# Laufender Betrieb

Zeitsteuerung, Protokoll, Makros, config.json, Systemaufgaben und häufige Fragen.

# Zeitsteuerung der Module (allgemein)

Jedes Modul bringt Aufgaben mit, die in Abständen laufen — Artikel exportieren, Bestellungen
holen, Mails ablegen. Verwaltet werden sie in der **Zeitsteuerung**. Diese Seite beschreibt,
was für alle Module gilt; welche Aufgaben es gibt, steht im Handbuch des jeweiligen Moduls.

![Zeitsteuerung Üebersicht](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zeitsteuerung-e6b92ddb-zeitsteuerung-uebersicht.png)

## Die Tabelle

| Spalte | Inhalt |
| -------------------------- | -------------------------------------------- |
| **Timer** | Name der Aufgabe, gruppiert nach Bereich |
| **letzte Ausführung** | Uhrzeit, oder *läuft…* bzw. *warten…* |
| **nächste Ausführung** | Uhrzeit des nächsten Starts |
| **Intervall** | der eingestellte Abstand |
| ▶ | startet die Aufgabe sofort |
| **Kategorie** | Untergruppe der Aufgabe |

Über **Aktualisieren** wird die Ansicht neu geladen; sie aktualisiert sich außerdem selbst.

<p class="callout info">Steht in der Spalte <em>Intervall</em> <code>00:00:00</code>, ist die Aufgabe nicht eingeplant. Sie läuft dann nur, wenn sie von Hand gestartet wird.</p>

## Intervall einstellen

Ein Klick auf die Uhrzeit in der Spalte **Intervall** öffnet die Eingabe.

![Intervall einstellen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zeitsteuerung-d028464a-zeitsteuerung-intervall.png)

Eingegeben wird eine Zeitspanne in **Stunden : Minuten : Sekunden**.

| Eingabe | Bedeutung | mit *Feste Zeit* |
| ------------ | ------------------------ | ---------------------------- |
| `00:15:00` | alle 15 Minuten | täglich 0:15 Uhr |
| `01:00:00` | jede Stunde | täglich 1:00 Uhr |
| `05:00:00` | alle 5 Stunden | täglich 5:00 Uhr |

### Feste Zeit

Ohne den Haken ist die Angabe ein **Abstand**, mit dem Haken eine **Uhrzeit**.

<p class="callout success">Für große Läufe — ein Vollexport aller Artikel — ist die feste Zeit der richtige Weg: einmal nachts, statt tagsüber alle paar Stunden.</p>

### Parallel ausführen

Normalerweise läuft **immer nur eine Aufgabe**. Ist eine andere aktiv, wartet die nächste und
zeigt *warten…*, bis sie an die Reihe kommt.

Mit dem Haken **Parallel ausführen** überspringt eine Aufgabe dieses Warten und läuft
gleichzeitig mit anderen.

<p class="callout success">Das ist Absicht und keine Einschränkung: Zwei Läufe, die dieselben Artikel schreiben, würden sich ins Gehege kommen. Die Warteschlange verhindert das.</p>

<p class="callout warning">Parallel gehört nur dort eingeschaltet, wo eine Aufgabe kurz ist und andere Daten anfasst — etwa der Abruf von Bestellungen, während nachts Artikel exportiert werden. Bei zwei Läufen auf denselben Daten führt es zu Fehlern, die schwer zu deuten sind.</p>

### Die Symbole

| Symbol | Bedeutung |
| ------------------ | -------------------------- |
| Pfeil im Kreis | Abstand |
| Uhr | feste Zeit |
| Unendlich-Zeichen | parallel |

## Zeitsteuerung ein- und ausschalten

Der Haken **Aktiv** in der Überschrift gilt für **alle Module dieser Installation**.

<p class="callout warning">Ausgeschaltet läuft keine Aufgabe mehr — und Änderungen an den Intervallen sind gesperrt. Das ist der Schalter für Wartungsarbeiten, nicht für den Dauerbetrieb.</p>

<p class="callout info">Ein Start über ▶ funktioniert trotzdem. Manuelle Läufe sind von <em>Aktiv</em> und vom Zeitfenster nicht betroffen.</p>

## Zeitfenster: Von und Bis

Neben *Aktiv* stehen zwei Felder, **Von** und **Bis**. Sind sie gefüllt, laufen die geplanten
Aufgaben nur innerhalb dieser Zeitspanne.

<p class="callout success">Damit lässt sich der Betrieb auf die Geschäftszeiten begrenzen — oder umgekehrt aus ihnen heraushalten, wenn die Datenbank tagsüber für die SelectLine frei bleiben soll.</p>

<p class="callout danger">Ein Fenster über Mitternacht wirkt <strong>nicht</strong>. Bei <em>Von 22:00</em> und <em>Bis 06:00</em> wird die Einschränkung übergangen und alle Aufgaben laufen wie ohne Fenster. Für nachts gehört das Fenster deshalb innerhalb eines Tages angegeben, etwa <em>Von 00:00 Bis 06:00</em>.</p>

<p class="callout info">Die Felder erscheinen nur in der Zeitsteuerung unter <strong>SelectLine</strong>. Das Fenster gilt aber für alle Module.</p>

## Von Hand starten

Die Schaltfläche ▶ startet eine Aufgabe sofort — unabhängig von Intervall, *Aktiv* und
Zeitfenster. Während sie läuft, ist sie ausgegraut.

<p class="callout info">Der manuelle Start umgeht auch die Warteschlange. Zwei große Läufe gehören deshalb nicht gleichzeitig von Hand gestartet.</p>

## Welche Daten eine Aufgabe berücksichtigt

Das hängt von der Aufgabe ab. Grob gilt:

| Art der Aufgabe | Berücksichtigt |
| ----------------------------------------------- | -------------------------------------- |
| Stammdaten synchronisieren, Extratabellen exportieren, Artikelgruppen exportieren, Bestand komplett, Kunden exportieren | alle Datensätze der betroffenen Tabellen |
| geänderte Artikel exportieren, Preise exportieren, Bestand geändert, Status exportieren | Datensätze, die seit dem Start des letzten Laufs geändert wurden |
| ein einzelner Artikel | zu diesem Artikel alles: Daten, Preis, Bestand, Bilder |
| XDATZUORD exportieren | geänderte Datensätze, deren Datei im Pfad vorhanden ist |

<p class="callout info">Bei <strong>XDATZUORD</strong> gilt zusätzlich: Fehlt die im Datensatz genannte Datei, wird der Datensatz übersprungen. Mehrfach genannte Dateien werden nur einmal übertragen.</p>

<p class="callout warning">Die Erkennung geänderter Datensätze stützt sich auf <em>geändert am</em>. Änderungen, die dieses Feld nicht setzen — etwa direkte Eingriffe in die Datenbank —, werden von den Änderungsläufen nicht erfasst. Dann hilft nur ein Vollauf.</p>

## Status und Meldungen

Unter der Tabelle stehen die aktuellen Meldungen des laufenden Betriebs.

![Statusmeldungen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-zeitsteuerung-3e3417c1-zeitsteuerung-status.png)

Das vollständige Protokoll steht unter [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Systemaufgaben

Neben den Modulaufgaben laufen eigene Aufgaben der Anwendung mit. Siehe
[Wartung und Systemaufgaben](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/wartung-und-systemaufgaben).

## Nächster Schritt

[Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen)

# Log Informationen

Das Protokoll ist die erste Stelle, an der man nachsieht, wenn etwas nicht wie erwartet
funktioniert. Jede Übertragung, jeder Fehler und jeder Start hinterlässt dort eine Zeile.

## Wo es zu finden ist

Über die Schaltfläche rechts oben in der Oberfläche.

![Schaltfläche für das Protokoll](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-log-c5b597c6-log-schaltflaeche.png)

![Die Protokollansicht](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-log-1f6a51d0-log-ansicht.png)

## Was angezeigt wird

Die **letzten 10.000 Einträge der letzten 24 Stunden**. Ältere Einträge stehen im Download.

| Spalte | Inhalt |
| ------------ | ---------------------------------------------- |
| **Typ** | `DEBUG`, `INFO`, `WARN` oder `ERROR` |
| **Datum** | Zeitpunkt |
| **Nachricht** | der Text; ein Klick auf die Zeile zeigt sie vollständig |

<p class="callout info">Lange Meldungen sind gekürzt. Ein Klick auf die Zeile klappt sie auf — dort steht auch, aus welchem Bereich der Anwendung sie stammt.</p>

## Die vier Typen

| Typ | Bedeutung | Handlungsbedarf |
| --------- | ------------------------------------------- | ------------------------ |
| `DEBUG` | Einzelschritte, für die Fehlersuche | keiner |
| `INFO` | normaler Ablauf: Start, Ende, Anzahl | keiner |
| `WARN` | etwas wurde übersprungen oder ersetzt | gelegentlich ansehen |
| `ERROR` | etwas ist nicht durchgelaufen | ansehen |

<p class="callout warning">Einzelne <code>ERROR</code>-Zeilen bedeuten nicht, dass ein Lauf insgesamt gescheitert ist — meist betrifft es einen Datensatz. Der Lauf gilt trotzdem als beendet. Der Abschluss allein sagt also nicht, dass alles angekommen ist.</p>

## Suchen und filtern

| Feld | Wirkung |
| ---------- | ---------------------------------------------- |
| **Suche** | Volltextsuche über die Meldungen |
| **Typ** | zeigt nur `INFO`, `DEBUG`, `WARN` oder `ERROR` |

<p class="callout success">Der schnellste Weg zur Ursache: auf <code>ERROR</code> filtern und von der ältesten Meldung nach vorne lesen. Der erste Fehler nennt die Ursache — die folgenden sind oft nur Folgefehler.</p>

## Zu jeder Zeile steht der Zusammenhang

Zu jeder Meldung wird vermerkt, aus welchem Aufruf sie stammt, welcher Pfad betroffen war und
welcher Benutzer beteiligt war.

<p class="callout success">Damit lässt sich ein Vorgang zusammenhängend nachlesen, statt einzelne Zeilen zusammenzusuchen — besonders wenn mehrere Module gleichzeitig protokollieren.</p>

## Das vollständige Protokoll herunterladen

Die Schaltfläche mit dem Pfeil lädt das gesamte Protokoll als **ZIP-Datei** herunter.

![Protokoll herunterladen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-log-a79fd047-log-download.png)

<p class="callout success">Das ist die Datei, die der DAKO-Support braucht. Sie enthält deutlich mehr als die Ansicht — auch die <code>DEBUG</code>-Zeilen und die älteren Tage.</p>

<p class="callout warning">Im Protokoll stehen Datensatznummern, Mailadressen und Namen aus dem Mandanten. Beim Weitergeben ist das zu berücksichtigen.</p>

## Wie lange die Dateien vorgehalten werden

Die Protokolldateien liegen im Ordner `log` der Installation. Es werden die letzten **10
Dateien** behalten; ältere werden gelöscht.

<p class="callout info">Bei einer sehr gesprächigen Installation deckt das nur wenige Tage ab. Wenn ein Fehler beobachtet werden soll, der nur selten auftritt, gehört das Protokoll deshalb zeitnah heruntergeladen.</p>

## Fehler per E-Mail

Fehler gehen zusätzlich per E-Mail heraus, wenn der Mailversand eingerichtet ist.

<p class="callout success">Das ist der Grund, den Mailversand einzurichten: Ohne ihn sieht niemand von selbst ins Protokoll — und eine Störung fällt erst auf, wenn ein Anwender sie meldet.</p>

Siehe [E-Mail-Versand](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-versand).

## Nächster Schritt

[Makros](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/makros)

# Makros

Mit Makros lassen sich Daten **vor oder nach** einer Übertragung noch verändern — ohne
Anpassung der Schnittstelle. Geschrieben werden sie in der SelectLine, eingetragen in
FINN.ghost.

<p class="callout success">Das ist der vorgesehene Weg für Sonderfälle: Ein Feld soll anders gefüllt, ein Text ergänzt, eine Auswahl anders getroffen werden. Was sich mit einem Makro lösen lässt, braucht keine Programmierung.</p>

## Wo die Felder stehen

In den Einstellungen der Module gibt es den Punkt **Makro**. Welche Makros ein Modul
anbietet, steht im Handbuch des Moduls.

![Makrofeld in den Einstellungen](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-makros-afbdb926-makros-feld.png)

## Was eingetragen wird

Der **Dateiname**, den die SelectLine dem Makro automatisch gibt — nicht seine Bezeichnung.

![Makro in der SelectLine](https://wiki.dako-it.com/uploads/images/gallery/2026-09/ghostdocs-finnghost-systemhandbuch-sys-makros-098ac218-makros-selectline.png)

<p class="callout danger">Das ist die häufigste Verwechslung: In der SelectLine ist die <em>Bezeichnung</em> sichtbar, gebraucht wird aber der <em>Dateiname</em>. Trägt man die Bezeichnung ein, wird das Makro nicht gefunden — und meist ohne auffällige Meldung übergangen.</p>

## Die Parameter müssen passen

Steht der Eingabecursor im Feld, zeigt FINN.ghost die **Parameter**, die das Makro
erwartet. Diese müssen im Makro gleichlautend vorhanden sein.

<p class="callout warning">Weicht ein Parametername ab, läuft das Makro nicht. Die Parameter sind die vereinbarte Schnittstelle zwischen FINN.ghost und dem Makro — sie gehören zeichengenau übernommen.</p>

## Was zu bedenken ist

<p class="callout danger">Ein Makro läuft bei <strong>jedem</strong> betroffenen Datensatz. Bei einem Vollexport mit zehntausenden Artikeln entscheidet seine Laufzeit über die Dauer des Laufs — ein Makro, das eine Sekunde braucht, verlängert den Export um Stunden.</p>

<p class="callout warning">Makros werden in der SelectLine ausgeführt und können dort schreiben. Vor dem Einsatz in einem echten Mandanten gehören sie in einem Testmandanten geprüft.</p>

## Wenn ein Makro nicht greift

| Ursache | Abhilfe |
| ------------------------------------------ | ------------------------------------ |
| Bezeichnung statt Dateiname eingetragen | Dateiname aus der SelectLine übernehmen |
| Parametername weicht ab | im Makro anpassen |
| Makro liegt im falschen Mandanten | im richtigen Mandanten anlegen |
| Makro läuft, wirkt aber nicht | prüfen, ob es vor oder nach der Übertragung greift |

Meldungen dazu stehen im Protokoll. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[Anpassungen über die config.json](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/anpassungen-uber-die-configjson)

# Anpassungen über die config.json

Alle Einstellungen von FINN.ghost stehen in einer Datei: der `config.json` im
Installationsordner. Fast alles darin wird über die Oberfläche gepflegt — für einige
Sonderfälle gibt es keine Maske.

<p class="callout danger">Diese Datei enthält die gesamte Konfiguration einschließlich der verschlüsselten Kennwörter. Änderungen von Hand nur mit angehaltenem Dienst und nur mit einer Kopie der bisherigen Datei — eine ungültige Datei verhindert den Start.</p>

## Wo sie liegt

```text
C:\DAKO\SelectLine.ghost\config.json
```

Der Pfad richtet sich nach dem gewählten Installationsordner.

| | |
| ------------------------- | -------------------------------------------- |
| **Beim Update** | wird nicht überschrieben |
| **Kennwortfelder** | werden verschlüsselt gespeichert |
| **`config.json.tmp`** | Sicherheitskopie |

## Die Sicherheitskopie

Im gleichen Verzeichnis liegt `config.json.tmp`. Sie wird **stündlich** von der Systemaufgabe
*Backup Config* geschrieben.

<p class="callout warning">Sie ist damit der Stand der letzten vollen Stunde — <strong>nicht</strong> der Stand unmittelbar vor der letzten Änderung. Wer eine Einstellung zurücknehmen will, findet dort den Stand von vorher nur, wenn seit der letzten Sicherung noch nichts geändert wurde.</p>

<p class="callout success">Vor größeren Änderungen deshalb selbst eine Kopie anlegen und mit Datum benennen. Das kostet nichts und erspart im Zweifel viel.</p>

Siehe [Wartung und Systemaufgaben](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/wartung-und-systemaufgaben).

## Vorgehen bei Änderungen von Hand

1. Windows-Dienst `SL_<Ordnername>` anhalten.
2. Kopie der `config.json` anlegen.
3. Ändern und die Datei als **gültiges JSON** speichern.
4. Dienst starten.
5. Im Protokoll prüfen, dass er gestartet ist.

<p class="callout danger">Wird bei laufendem Dienst geändert, geht die Änderung verloren: Die Anwendung hält die Einstellungen im Speicher und schreibt die Datei beim nächsten Speichern komplett neu.</p>

## Dateien im Dateisystem ablegen

Standardmäßig legt FINN.ghost die Dateien von Journalen in der Datenbank ab. Sollen sie
stattdessen im Dateisystem liegen, wird der Pfad zum **SYSTEM-Ordner der SelectLine**
hinterlegt:

```json
{
  "systemPath": "\\sql03\SelectLineSQL2022_SRV\SYSTEM"
}
```

<p class="callout info">Läuft FINN.ghost nicht auf demselben System wie die SelectLine, muss es ein <strong>Netzwerkpfad</strong> sein. Im JSON werden Backslashes doppelt geschrieben — <code>\</code> statt <code>\</code>.</p>

<p class="callout warning">Der Benutzer, unter dem der Windows-Dienst läuft, braucht Schreibrechte auf diesen Pfad. Läuft der Dienst als lokales Systemkonto, hat er auf einem Netzwerkpfad in der Regel keine Rechte — dann gehört dem Dienst ein Domänenkonto zugewiesen.</p>

### Datenbank oder Dateisystem

| | Datenbank (Standard) | Dateisystem |
| --------------------- | ------------------------------ | ---------------------------- |
| In der Datensicherung | enthalten | nur wenn der Ordner mitgesichert wird |
| Größe der Datenbank | wächst mit den Dateien | bleibt klein |
| Zugriff | nur über die SelectLine | auch direkt im Ordner |

<p class="callout success">Bei FINN.mail2SL lohnt die Überlegung: Dort entsteht je abgelegter Mail eine Datei. Über Jahre summiert sich das in der Datenbank deutlich.</p>

## Einstellungen, die es nur hier gibt

Ein Teil der Einstellungen hat keine Maske: eigene Abfragen für die Bestandsermittlung,
Zuordnungen einzelner Felder und Sonderfälle der einzelnen Module. Welche das sind und was
sie bewirken, steht im Kapitel
[Einstellungen ohne Maske](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/grundlagen).

## Was hier nicht geändert werden sollte

<p class="callout warning">Alles, wofür es eine Maske gibt, gehört über die Oberfläche geändert — dort werden Werte geprüft, Kennwörter verschlüsselt und nötige Neustarts ausgelöst. Der direkte Eingriff ist für die Fälle gedacht, die keine Maske haben.</p>

Eine Ausnahme ist der Notfall: Hat man sich durch die eingeschaltete Benutzeranmeldung
ausgesperrt, lässt sie sich hier zurücksetzen. Siehe
[Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache).

## Nächster Schritt

[Wartung und Systemaufgaben](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/wartung-und-systemaufgaben)

# Wartung und Systemaufgaben

Neben den Aufgaben der Module laufen eigene Aufgaben der Anwendung. Sie stehen in der
Zeitsteuerung unter der Kategorie **System**.

## Die Systemaufgaben

| Aufgabe | Abstand | Was sie tut |
| ------------------------------ | ---------- | ------------------------------------ |
| **Backup Config** | stündlich | schreibt `config.json.tmp` und meldet den Stand der Installation an DAKO-IT |
| **MSSQL-Log aufräumen** | eingeplant | verkleinert das Transaktionsprotokoll der Datenbank |
| **SSL Zertifikat erneuern** | alle 12 Stunden | erneuert das Let's-Encrypt-Zertifikat, wenn es nötig ist |

Dazu je Modul dessen eigene Aufgaben. Siehe
[Zeitsteuerung der Module (allgemein)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).

## MSSQL-Log aufräumen

Diese Aufgabe verkleinert das Transaktionsprotokoll der Mandantendatenbank. Dazu stellt sie
das Wiederherstellungsmodell kurzzeitig auf **Einfach**, verkleinert die Protokolldatei und
stellt das Modell wieder auf **Vollständig**.

<p class="callout success">Der Grund ist praktischer Natur: Massenläufe wie ein Artikelvollexport lassen das Transaktionsprotokoll stark anwachsen. Ohne Verkleinerung läuft die Platte über.</p>

<p class="callout danger">Der Wechsel des Wiederherstellungsmodells <strong>unterbricht die Kette der Protokollsicherungen</strong>. Wer die SelectLine-Datenbank mit Transaktionsprotokollsicherungen sichert, muss danach eine neue Vollsicherung anstoßen — sonst ist eine zeitpunktgenaue Wiederherstellung nicht mehr möglich. Diese Aufgabe gehört deshalb mit dem Datenbankverantwortlichen abgestimmt.</p>

<p class="callout info">Wird die Datenbank ohnehin im Modell <em>Einfach</em> betrieben — bei SelectLine-Installationen verbreitet —, ist das ohne Bedeutung.</p>

## Was stündlich an DAKO-IT gemeldet wird

Die Aufgabe *Backup Config* meldet zusammen mit der Sicherung den Stand der Installation an
einen Dienst von DAKO-IT. Übertragen werden:

| Angabe | Wozu |
| --------------------------------- | ------------------------------------------ |
| Lizenzschlüssel | Prüfung, ob die Lizenz noch gültig ist |
| Firmenname aus der SelectLine-Lizenz | Zuordnung zum Kunden |
| Mandant | Zuordnung der Installation |
| Version der SelectLine | Unterstützung und Fehlersuche |
| Version von FINN.ghost | Hinweis auf verfügbare Updates |
| Installationspfad und Rechnername | Unterscheidung mehrerer Installationen |

<p class="callout info">Es werden keine Belege, Adressen oder Artikel übertragen — nur die genannten Angaben zur Installation.</p>

<p class="callout danger">Meldet der Dienst die Lizenz als <strong>abgelaufen</strong>, wird der Lizenzschlüssel geleert und die Anwendung beendet sich. Sie startet danach ohne Module. Bei einer auslaufenden Lizenz gehört die Verlängerung deshalb rechtzeitig geklärt.</p>

<p class="callout warning">Ohne ausgehende Internetverbindung schlägt diese Meldung fehl. Das ist für den Betrieb unkritisch — im Protokoll erscheint dann aber regelmäßig ein Fehler.</p>

## Was in die Datensicherung gehört

| Was | Warum |
| ------------------------------------- | ------------------------------------------ |
| `config.json` | die gesamte Konfiguration |
| Ordner `data\ssl` | Zertifikat, Schlüssel und Let's-Encrypt-Zugang |
| Ordner `client\plugins` | eigene Erweiterungen, falls vorhanden |
| Datenbank des Mandanten | dort liegen die Daten der Module |

<p class="callout success">Mit <code>config.json</code> und <code>data\ssl</code> ist eine Installation nach einem Serverausfall in wenigen Minuten wiederhergestellt: Setup ausführen, beides zurückkopieren, Dienst starten.</p>

<p class="callout info">Das Programm selbst braucht nicht gesichert zu werden — das Setup lässt sich jederzeit neu herunterladen. </p>

Siehe [Installation und Update](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/installation-und-update).

## Regelmäßig nachsehen

| Wie oft | Was |
| ------------ | ------------------------------------------------- |
| täglich | die Fehlermails, sofern eingerichtet |
| wöchentlich | Protokoll auf wiederkehrende `ERROR`-Meldungen |
| monatlich | läuft eine aktuelle Version? |
| monatlich | Restlaufzeit des Zertifikats |
| jährlich | Ablaufdatum von Clientschlüsseln bei Microsoft 365 |

<p class="callout warning">Der letzte Punkt fällt in der Praxis am häufigsten auf: Clientschlüssel in Azure laufen nach ein bis zwei Jahren ab. Danach steht der Mailversand — und damit auch die Benachrichtigung, die darauf hinweisen würde.</p>

Siehe [E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365).

## Nächster Schritt

[Häufige Fragen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/haufige-fragen)

# Häufige Fragen

## Wo läuft FINN.ghost?

Als Windows-Dienst auf einem Server im Haus. Bedient wird es im Browser. Siehe
[Überblick](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/uberblick).

## Braucht FINN.ghost eine eigene Datenbank?

Nein. Was gespeichert werden muss, legt es in eigenen Tabellen im SelectLine-Mandanten ab.
Deshalb braucht der SQL-Benutzer das Recht, Tabellen anzulegen. Siehe
[Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank).

## Warum werden Datenbank **und** API gebraucht?

Gelesen wird direkt aus der Datenbank, weil das bei großen Mengen um ein Vielfaches
schneller ist. Geschrieben wird über die API, damit Nummernkreise, Preisfindung und
Buchungen der SelectLine gelten. Siehe [SelectLine-API](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/selectline-api).

## Können mehrere FINN.ghost auf einem Server laufen?

Ja. Jede Installation braucht einen eigenen Ordner und einen eigenen Port. Der Ordnername
wird zum Dienstnamen — sprechende Namen erleichtern die Unterscheidung. Siehe
[Installation und Update](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/installation-und-update).

## Können mehrere Mandanten mit einer Installation bedient werden?

Nein. Eine Installation arbeitet auf einer Mandantendatenbank. Für einen zweiten Mandanten
braucht es eine zweite Installation. Siehe [Datenbank](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/datenbank).

## Wie aktualisiere ich?

In der Oberfläche **Strg + Alt + U**. Alternativ das Setup über denselben Ordner ausführen.
Siehe [Installation und Update](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/installation-und-update).

## Bleiben die Einstellungen beim Update erhalten?

Ja, die `config.json` wird nicht überschrieben. Siehe
[Anpassungen über die config.json](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/anpassungen-uber-die-configjson).

## Warum warnt der Browser vor der Verbindung?

Weil das Zertifikat nicht anerkannt wird. Mit öffentlicher Domain löst das
[Let's Encrypt](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/ssl-mit-lets-encrypt), ohne Domain das Verteilen des Stammzertifikats an die
Arbeitsplätze — siehe [Zertifikat einrichten](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zertifikat-einrichten).

## Muss FINN.ghost aus dem Internet erreichbar sein?

Für Let's Encrypt nicht — der Nachweis läuft über einen DNS-Eintrag. Einzelne Module
brauchen aber eingehende Verbindungen, etwa für Rückmeldungen eines Shops. Das steht im
jeweiligen Modulhandbuch.

## Warum fehlt ein Modul im Menü?

Weil die Lizenz es nicht enthält oder nach dem Speichern noch nicht neu gestartet wurde.
Siehe [Lizenz und Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/lizenz-und-module).

## Eine Aufgabe steht auf „warten…" — ist das ein Fehler?

Nein. Es läuft gerade eine andere Aufgabe; es wird immer nur eine ausgeführt. Siehe
[Zeitsteuerung der Module (allgemein)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).

## Warum läuft nachts alles, obwohl ich ein Zeitfenster gesetzt habe?

Weil ein Fenster über Mitternacht nicht wirkt. *Von 22:00 Bis 06:00* wird übergangen. Das
Fenster muss innerhalb eines Tages liegen. Siehe
[Zeitsteuerung der Module (allgemein)](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).

## Ein Lauf ist beendet — sind damit alle Daten übertragen?

Nicht zwangsläufig. Einzelne Datensätze können gescheitert sein; der Lauf gilt trotzdem als
beendet. Sicherheit gibt nur das Protokoll. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Wie lange bleiben Protokolle erhalten?

Die Ansicht zeigt 24 Stunden, auf der Platte liegen die letzten 10 Protokolldateien. Wer mehr
braucht, lädt das Protokoll als ZIP herunter. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Was braucht der Support von mir?

Das Protokoll als ZIP, die Version aus der Fußzeile und eine Beschreibung, welcher Vorgang
betroffen ist. Siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Der Mailversand läuft nicht mehr, ohne dass sich etwas geändert hat.

Meist ist ein Clientschlüssel in Azure abgelaufen. Siehe
[E-Mail über Microsoft 365](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/e-mail-uber-microsoft-365).

## Wer darf die Oberfläche öffnen?

Ohne eingeschaltete Benutzeranmeldung jeder, der den Server im Netz erreicht. Für alles
außerhalb von `localhost` gehört sie eingeschaltet. Siehe
[Server und Oberfläche](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/server-und-oberflache).

## Kann ich FINN.ghost in der SelectLine anzeigen?

Ja, die Oberfläche lässt sich in den SelectLine-Dashboards einbinden. Die Anwender bleiben
dann in der SelectLine.

## Wie entferne ich eine Installation?

Dienst anhalten und entfernen, Ordner löschen. Vorher die `config.json` sichern. Siehe
[Installation und Update](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/installation-und-update).

## Wo steht, was sich geändert hat?

Im [Änderungsverlauf](https://wiki.dako-it.com/books/finnghost-anderungsverlauf) — und auf
der Startseite der Anwendung.

# Einstellungen ohne Maske

Einstellungen, die es nur in der config.json gibt: Bestandsberechnung über eigene Abfragen, Feldzuordnungen und Sonderfälle der einzelnen Module.

# Grundlagen

Die meisten Einstellungen von FINN.ghost haben eine Maske in der Oberfläche. Ein Teil hat
keine — sie entstanden für einzelne Installationen und werden ausschließlich in der
`config.json` gepflegt. Dieses Kapitel führt sie auf.

<p class="callout warning">Diese Einstellungen sind bewusst nicht in der Oberfläche. Sie greifen tief in den Ablauf einer Übertragung ein, und ein falscher Wert fällt oft erst auf, wenn im Shop falsche Bestände oder falsche Preise stehen. Wer sie setzt, sollte wissen, was der jeweilige Lauf sonst tun würde.</p>

## Wie sie eingetragen werden

Der Schlüssel steht in der `config.json` unter dem Abschnitt des Moduls. Der Teil vor dem
Punkt ist der Abschnitt, der Teil dahinter der Name in diesem Abschnitt:

```json
{
  "sw6": {
    "customStock": "SELECT ... AS Bestand FROM ...",
    "ignoreReserved": true
  },
  "shopify": {
    "zeroStockField": "_KEINBESTAND"
  }
}
```

Die Abschnitte der Module:

| Abschnitt | Modul |
| ------------- | ------------------------------ |
| `sw6` | Shopware 6 |
| `shopify` | Shopify |
| `shop` | FINN.webshop |
| `gmi` | GetMyInvoices |
| `mail2sl` | FINN.mail2SL |
| `mcp` | FINN.AI MCP |
| ohne Abschnitt | gilt für die ganze Installation |

<p class="callout danger">Geändert wird nur bei angehaltenem Dienst und nur mit einer Kopie der bisherigen Datei. Bei laufendem Dienst geht die Änderung verloren, weil die Anwendung die Einstellungen im Speicher hält und die Datei beim nächsten Speichern komplett neu schreibt. Das Vorgehen steht unter <a href="sys-configjson">Anpassungen über die config.json</a>.</p>

## Was die Werte bedeuten

Die Tabellen dieses Kapitels nennen je Einstellung den Typ. Vier kommen vor:

| Typ | Bedeutung |
| ------------------- | ----------------------------------------------------------- |
| **Schalter** | `true` oder `false`. Fehlt der Schlüssel, gilt die Vorgabe. |
| **Feldname** | Name einer Spalte oder eines Extrafelds in der SelectLine — zeichengenau, ohne Tabellenpräfix. |
| **Abfrage** | vollständige SQL-Abfrage als Text, mit Platzhalter (siehe [Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge)). |
| **Wert** | eine Zahl oder ein Text, etwa eine Preisgruppe oder ein Belegtyp. |

<p class="callout info">Bei den Einstellungen vom Typ <strong>Feldname</strong> wird ein Flag in der SelectLine ausgewertet. Gemeint ist dabei durchgängig ein Ja/Nein-Extrafeld, das als Text <code>True</code> gespeichert wird — so legt die SelectLine Ja/Nein-Extrafelder ab.</p>

<p class="callout warning">Ein Feldname, den es in der Mandantendatenbank nicht gibt, führt zu einem Fehler in der Abfrage — nicht zu einer Meldung in der Oberfläche. Steht ein Lauf plötzlich mit einem SQL-Fehler im Protokoll, ist ein Tippfehler in einem dieser Felder die erste Vermutung.</p>

## Aufbau des Kapitels

| Seite | Inhalt |
| ---------------------------------------------------------- | ---------------------------------------------- |
| [Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge) | eigene Abfragen für Bestand und maximale Bestellmenge, für alle drei Shops |
| [Shopware 6](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/shopware-6) | Artikel, Artikelgruppen, Kunden, Belege |
| [Shopify](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/shopify) | Artikel, Belege, Kunden, B2B |
| [Weitere Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/weitere-module) | FINN.webshop, Bilder, Oberfläche, SelectLine, GMI, mail2SL, MCP |

<p class="callout success">Vieles, was diese Einstellungen leisten, geht auch mit einem Makro — und ein Makro ist in der Oberfläche sichtbar und dokumentiert sich damit selbst. Wo beides möglich ist, ist das Makro der bessere Weg. Siehe <a href="sys-makros">Makros</a>.</p>

## Nächster Schritt

[Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge)

# Bestand und Bestellmenge

Standardmäßig ermittelt FINN.ghost den Bestand eines Artikels aus der SelectLine-Ansicht
`SL_vGetFreierArtikelBestand`: **Bestand minus Reserviert**, bei Stücklisten die kleinste
Stückzahl, die sich aus den Bestandteilen bauen lässt. Für alle Fälle, in denen das nicht
passt, gibt es `customStock` — eine eigene SQL-Abfrage, die den Bestand liefert.

<p class="callout success">Typische Gründe: Es sollen nur bestimmte Läger in den Shop gemeldet werden, ein Sicherheitsbestand soll abgezogen werden, oder ein Sperrlager soll unberücksichtigt bleiben.</p>

## customStock

Alle drei Shop-Anbindungen kennen die Einstellung. Der Schlüssel ist derselbe, Abschnitt
und Platzhalter unterscheiden sich:

| Anbindung | Schlüssel | Platzhalter |
| -------------- | --------------------- | ---------------------- |
| Shopware 6 | `sw6.customStock` | `${article.Number}` |
| Shopify | `shopify.customStock` | `${nummer}` |
| FINN.webshop | `shop.customStock` | `${artikelnummer}` |

<p class="callout danger">Der Platzhalter ist je Anbindung ein anderer. Wird der falsche verwendet, wird er nicht ersetzt — die Abfrage läuft dann mit dem Text <code>${nummer}</code> als Artikelnummer, findet nichts und liefert Bestand <strong>0</strong> für jeden Artikel.</p>

### Was die Abfrage liefern muss

Eine Spalte mit dem Namen **`Bestand`**. Ausgewertet wird die **erste Zeile** des
Ergebnisses.

Das Beispiel meldet nur die Läger `01` und `02` und zieht die reservierte Menge ab:

```json
{
  "sw6": {
    "customStock": "SELECT SUM(ISNULL(Bestand,0)-ISNULL(Reserviert,0)) AS Bestand FROM dbo.SL_vGetFreierArtikelBestandMitLager WHERE Artikelnummer = '${article.Number}' AND Lager IN ('01','02')"
  }
}
```

<p class="callout success">Die Ansicht <code>SL_vGetFreierArtikelBestandMitLager</code> ist für solche Abfragen der bequemste Einstieg: dieselben Werte wie in der Standardberechnung, nur zusätzlich je Lager. Für Standorte statt Läger gibt es <code>SL_vGetFreierArtikelBestandMitStandort</code>.</p>

| | |
| ----------------------------------- | --------------------------------------------- |
| **Spalte heißt nicht `Bestand`** | Ergebnis wird als 0 gewertet |
| **Abfrage liefert keine Zeile** | Bestand 0 |
| **Ergebnis ist negativ** | wird auf 0 angehoben |
| **Mehrere Zeilen** | nur die erste zählt |

<p class="callout warning">Der Wert wird als ganze Zahl übertragen. Nachkommastellen fallen weg — bei Artikeln, die in Metern oder Kilogramm geführt werden, ist das zu bedenken.</p>

### Was die Abfrage ersetzt

Ist `customStock` gesetzt, entscheidet **allein** die Abfrage. Die Standardlogik läuft
nicht mehr — und damit auch nichts, was daran hängt:

| Läuft nicht mehr | Folge |
| ----------------------------- | --------------------------------------------- |
| Abzug von **Reserviert** | muss in der Abfrage selbst stehen |
| Auflösung von **Stücklisten** | Set- und Behälterartikel liefern den Wert der Abfrage, nicht die baubare Menge |

<p class="callout danger">Die Stücklistenauflösung ist der Punkt, der am häufigsten übersehen wird. Ohne <code>customStock</code> meldet FINN.ghost für einen Set-Artikel die Menge, die sich aus den Bestandteilen bauen lässt. Mit <code>customStock</code> liefert die Abfrage den Wert — und der eigene Lagerbestand eines Set-Artikels ist in der Regel 0.</p>

Welche Artikel überhaupt übertragen werden, ändert `customStock` **nicht**: Die Auswahl
nach *Shopaktiv* und *Inaktiv* passiert davor, beim Zusammenstellen der Artikelliste. Ein
nicht shopaktiver Artikel wird also weiterhin gar nicht erst gemeldet.

<p class="callout warning">Bei <strong>Shopify</strong> ist das anders: Dort gehört die Prüfung auf <em>Shopaktiv</em> und <em>Inaktiv</em> zur Bestandsermittlung selbst und wird von <code>shopify.customStock</code> mit übergangen — ebenso <code>shopify.zeroStockField</code>. Beides gehört dann in die Abfrage.</p>

### Rückfall auf die Standardberechnung (nur Shopware 6)

Bei Shopware 6 gibt es einen Ausweg für einzelne Artikel: Liefert die Abfrage den Wert
**`-9999`**, verwirft FINN.ghost das Ergebnis und rechnet für diesen Artikel wie ohne
`customStock`.

```sql
SELECT CASE WHEN ... THEN 0 ELSE -9999 END AS Bestand FROM ART WHERE Artikelnummer = '${article.Number}'
```

<p class="callout success">Damit lässt sich die Sonderlogik auf die Artikel beschränken, die sie brauchen. Alle anderen laufen weiter über die geprüfte Standardberechnung — inklusive Stücklistenauflösung.</p>

<p class="callout info">Shopify und FINN.webshop kennen diesen Rückfall nicht. Dort gilt die Abfrage für jeden Artikel.</p>

### Besonderheit bei Shopify

Shopify führt Bestände je Standort. `shopify.customStock` liefert **einen** Wert, und
dieser wird auf **alle** eingerichteten Standorte geschrieben — nicht aufgeteilt.

<p class="callout warning">Bei mehreren Standorten summiert Shopify die Bestände. Ein Wert von 10 bei drei Standorten wird im Shop zu 30 verfügbaren Stück. Wer mit mehreren Standorten arbeitet, sollte <code>customStock</code> dort nicht einsetzen.</p>

Zusätzlich greift die Abfrage nur, wenn die Bestandsführung für den Artikel aktiv ist.
Ist sie abgeschaltet, überträgt Shopify keinen Bestand — dann läuft die Abfrage nicht.

## Weitere Einstellungen zum Bestand

### Shopware 6

| Schlüssel | Typ | Wirkung |
| --------------------- | -------- | ------------------------------------------------------- |
| `sw6.ignoreReserved` | Schalter | rechnet mit **Bestand** statt Bestand minus Reserviert. Reservierungen aus offenen Aufträgen mindern den Shopbestand dann nicht. |
| `sw6.customPurchase` | Abfrage | eigene Abfrage für die **maximale Bestellmenge**. Platzhalter `${article}`, Spalte `Bestand`. |
| `sw6.maxPurchaseField` | Feldname | Artikelfeld mit der maximalen Bestellmenge je Artikel. |

<p class="callout warning">Ist <code>sw6.maxPurchaseField</code> gesetzt und im Artikel gefüllt, gilt dieser Wert — <code>sw6.customPurchase</code> kommt dann für diesen Artikel nicht mehr zum Zug. Das Feld hat Vorrang.</p>

<p class="callout info"><code>sw6.ignoreReserved</code> wirkt nur, wenn <code>sw6.customStock</code> <strong>nicht</strong> gesetzt ist oder für den Artikel <code>-9999</code> liefert. Sonst rechnet ohnehin nur die eigene Abfrage.</p>

### Shopify

| Schlüssel | Typ | Wirkung |
| ------------------------------------- | -------- | --------------------------------------- |
| `shopify.zeroStockField` | Feldname | Artikelfeld; ist es `True`, wird Bestand **0** gemeldet, obwohl Bestand vorhanden ist. Wirkt auch über den Variantenartikel und über Stücklisten: hat ein Bestandteil das Feld gesetzt, ist die ganze Stückliste 0. |
| `shopify.inventoryTrackDisableField` | Feldname | Artikelfeld; ist es `True`, wird die **Bestandsführung** für diesen Artikel in Shopify abgeschaltet. Der Artikel ist dann unbegrenzt bestellbar. |

<p class="callout success"><code>shopify.zeroStockField</code> ist der saubere Weg, einzelne Artikel im Shop auf nicht verfügbar zu setzen, ohne sie in der SelectLine anzufassen — und deutlich einfacher als eine eigene Abfrage.</p>

## Wenn der Bestand im Shop nicht stimmt

| Beobachtung | Erste Prüfung |
| ------------------------------------------ | ------------------------------------------------ |
| **alle** Artikel stehen auf 0 | Platzhalter falsch geschrieben, oder Spalte heißt nicht `Bestand` |
| Stücklisten stehen zu niedrig | `customStock` löst Stücklisten nicht auf |
| bei Shopify: gesperrte Artikel bestellbar | `shopify.zeroStockField` wird von der Abfrage übergangen |
| Shopify zeigt ein Vielfaches | mehrere Standorte, der Wert wird je Standort geschrieben |
| Bestand ändert sich nicht mehr | Lauf steht mit SQL-Fehler im Protokoll |

Die Abfrage lässt sich vor dem Eintragen im SQL Management Studio prüfen — dort den
Platzhalter durch eine echte Artikelnummer ersetzen. Meldungen der Läufe stehen im
Protokoll, siehe [Log Informationen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/log-informationen).

## Nächster Schritt

[Shopware 6](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/shopware-6)

# Shopware 6

Alle Schlüssel dieser Seite stehen in der `config.json` im Abschnitt `sw6`. Was der
Artikelexport im Regelfall überträgt, steht im
[Handbuch für Shopware 6](https://wiki.dako-it.com/books/finnghost-fur-shopware6-wHZ).

## Artikeltexte und Bezeichnungen

| Schlüssel | Typ | Wirkung |
| ----------------------------------- | -------- | -------------------------------------------- |
| `titleField` | Feldname | Extrafeld, dessen Inhalt als **Produktname** übertragen wird — statt der Artikelbezeichnung. |
| `descriptionField` | Feldname | Extrafeld, dessen Inhalt als **Beschreibung** übertragen wird — statt des Artikeltexts. Zeilenumbrüche werden zu `<br>`. |
| `disableDescription` | Schalter | überträgt **keine** Beschreibung. Vorhandene Texte im Shop bleiben unangetastet. |
| `disableManufacturerDescription` | Schalter | überträgt keine Beschreibung zum Hersteller. |
| `customSearchKeywordsField` | Feldname | Artikelfeld, aus dessen Inhalt die **Suchworte** des Produkts gebildet werden. |
| `zusatzInTitleSeparator` | Wert | Trennzeichen zwischen Bezeichnung und Zusatz, Vorgabe `" - "`. Wirkt nur, wenn *Zusatz im Titel* eingeschaltet ist. |

<p class="callout warning"><code>disableDescription</code> ist der übliche Weg, wenn die Beschreibungen im Shop redaktionell gepflegt werden. Ohne diesen Schalter überschreibt jeder Artikelexport den Text im Shop mit dem Artikeltext aus der SelectLine — die redaktionelle Arbeit wäre beim nächsten Lauf weg.</p>

<p class="callout info"><code>titleField</code> und <code>descriptionField</code> lesen <strong>Extrafelder</strong> über die SelectLine-API, <code>customSearchKeywordsField</code> liest eine <strong>Spalte der Tabelle ART</strong> direkt per SQL. Für <code>customSearchKeywordsField</code> ist deshalb der Spaltenname anzugeben, für die anderen beiden der Name des Extrafelds.</p>

## Preise, Grundpreise und Datumsfelder

| Schlüssel | Typ | Wirkung |
| ----------------------------- | -------- | ------------------------------------------------ |
| `disableSafeguardPriceField` | Feldname | Artikelfeld; ist es `True`, wird ein Artikel **ohne Preis** mit Preis 0 übertragen, statt übersprungen zu werden. |
| `grundpreisMengumField` | Feldname | Feld in den Mengeneinheiten (`MENGUM`); die so markierte Mengeneinheit liefert Grundpreis-Einheit und Faktor. |
| `grundpreisReferenceField` | Feldname | Artikelfeld mit der **Bezugsmenge** des Grundpreises. Vorgabe `FreierText2`. |
| `grundpreisUnitField` | Feldname | Artikelfeld mit der **Einheit** des Grundpreises. Vorgabe `FreieZahl3`. |
| `releaseDateField` | Feldname | Extrafeld, dessen Datum als **Erscheinungsdatum** übertragen wird. Ohne die Angabe gilt das Anlagedatum des Artikels. |
| `restockTimeField` | Feldname | Extrafeld mit der **Wiederauffüllzeit** in Tagen. |

<p class="callout danger">Die drei <code>grundpreis</code>-Schlüssel wirken nur, wenn der Grundpreis-Export überhaupt eingeschaltet ist. Ist <code>grundpreisMengumField</code> gesetzt, hat es Vorrang; erst ohne dieses Feld werden die beiden Artikelfelder gelesen. Die Vorgaben <code>FreierText2</code> und <code>FreieZahl3</code> greifen also auch dann, wenn nichts eingetragen ist — was zu Grundpreisen aus einem Feld führen kann, das für etwas anderes genutzt wird.</p>

<p class="callout warning">Ohne <code>disableSafeguardPriceField</code> übergeht FINN.ghost Artikel ohne gültigen Preis absichtlich und schreibt eine Meldung ins Protokoll. Der Schalter ist für Artikel gedacht, die im Shop bewusst mit 0 stehen sollen — er sollte nicht dazu dienen, fehlende Preise zu verdecken.</p>

## Zusatzfelder umbenennen

| Schlüssel | Typ | Wirkung |
| -------------------------- | ------- | ------------------------------------------------------ |
| `extrafeldMapping` | Liste | benennt Zusatzfelder beim Übertragen um. |
| `extrafeldMappingDelete` | Schalter | Vorgabe `true`: das Ursprungsfeld wird nach dem Umbenennen entfernt. Mit `false` bleiben **beide** Felder erhalten. |

```json
{
  "sw6": {
    "extrafeldMapping": [
      { "old": "custom_sl_artikel_FreierText1", "new": "custom_meine_farbe" }
    ],
    "extrafeldMappingDelete": false
  }
}
```

<p class="callout info">Die Umbenennung greift auch in den Übersetzungen, sofern Sprachen eingerichtet sind. Das Zielfeld muss in Shopware als Zusatzfeld existieren — angelegt wird es dabei nicht.</p>

## Artikelgruppen und Kategorien

| Schlüssel | Typ | Wirkung |
| ----------------------------------- | -------- | ------------------------------------------- |
| `shopaktivArtikelGruppenFeld` | Feldname | Feld an der Artikelgruppe; nur Gruppen mit `True` werden als Kategorie übertragen. |
| `artikelgruppenNichtAktualisieren` | Schalter | bestehende Kategorien werden **nicht** mehr aktualisiert. Neue werden weiter angelegt. |

<p class="callout success"><code>artikelgruppenNichtAktualisieren</code> ist für Shops gedacht, deren Kategoriebaum in Shopware weitergepflegt wird — mit eigenen Bezeichnungen, eigener Sortierung oder eigener Einordnung. Ohne den Schalter zieht jeder Lauf die Kategorien wieder auf den Stand der SelectLine.</p>

## Varianten und Bilder

| Schlüssel | Typ | Wirkung |
| --------------------- | -------- | ---------------------------------------------------- |
| `auffaechernDefault` | Schalter | **alle** Variantenartikel werden in der Storefront aufgefächert, unabhängig vom dafür eingerichteten Artikelfeld. |
| `useHashAsFilename` | Schalter | Bilddateien werden unter einem Prüfsummennamen abgelegt statt unter *Hersteller-Bezeichnung*. |

<p class="callout info">Ist <code>auffaechernDefault</code> gesetzt, greift die Einstellung <em>Erste Variante in der Storefront anzeigen</em> nicht mehr — beides zusammen ergibt keinen Sinn.</p>

<p class="callout warning"><code>useHashAsFilename</code> hilft, wenn Bezeichnungen Zeichen enthalten, die als Dateiname Probleme machen. Nach dem Umstellen entstehen für bereits übertragene Bilder neue Dateien; die alten bleiben in der Shopware-Medienverwaltung liegen und müssen dort aufgeräumt werden.</p>

## Makro vor dem Artikelexport

| Schlüssel | Typ | Wirkung |
| --------------------- | ---- | ----------------------------------------------------- |
| `preExportArticles` | Wert | Dateiname eines SelectLine-Makros, das **vor jedem einzelnen Artikel** ausgeführt wird. Übergeben wird der Parameter `Nummer` mit der Artikelnummer. |

<p class="callout danger">Das Makro läuft je Artikel — bei einem Vollexport also zehntausende Male. Seine Laufzeit bestimmt damit die Dauer des ganzen Laufs. Eingetragen wird der <strong>Dateiname</strong> des Makros, nicht seine Bezeichnung; siehe <a href="sys-makros">Makros</a>.</p>

<p class="callout info">Bei Shopify und FINN.webshop gibt es dasselbe Makro in den Einstellungen der Oberfläche. Nur bei Shopware 6 fehlt die Maske dafür.</p>

## Kunden

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | --------------------------------------------- |
| `kdfeld` | Feldname | Kundenfeld, in dem die **Shop-Kundennummer** steht. Vorgabe `Shopnummer`. |
| `disableCustomerCreate` | Schalter | im Shop werden **keine** neuen Kunden angelegt. Bestehende werden weiter aktualisiert. |
| `onlyUpdateZahlungsbedingung` | Schalter | überträgt von bestehenden Kunden **nur** die Zahlungsbedingung, sonst nichts. |

<p class="callout success">Die Kombination aus beiden Schaltern ist der Weg für Shops, in denen die Kundenpflege im Shop stattfindet und aus der SelectLine nur die Zahlungsbedingung nachgeführt werden soll.</p>

## Belege

| Schlüssel | Typ | Wirkung |
| ---------------------------------- | -------- | ------------------------------------------ |
| `defaultWarehouseLocationNumber` | Wert | Lagerplatz, der in jeden importierten Beleg geschrieben wird. |
| `slPriceToleranceField` | Feldname | Belegfeld, in das bei einer **Preisabweichung** zwischen Shop und SelectLine der Hinweistext geschrieben wird. |

<p class="callout warning">Eine Preisabweichung landet in jedem Fall als Fehler im Protokoll. <code>slPriceToleranceField</code> macht sie zusätzlich am Beleg sichtbar, damit sie in der SelectLine auffällt und nicht nur im Protokoll steht.</p>

## Technische Sonderfälle

| Schlüssel | Typ | Wirkung |
| ---------------- | -------- | ------------------------------------------------------------- |
| `oldSWVersion` | Schalter | schreibt die Zeiträume von Preisregeln im Format älterer Shopware-Versionen. |
| `appServerUrl` | Wert | Adresse, die Shopware zur Bestätigung der App zurückruft. Vorgabe `https://localhost:8080`. |

<p class="callout info"><code>appServerUrl</code> wird nur für die App-Registrierung gebraucht und muss die Adresse sein, unter der Shopware diese FINN.ghost-Installation erreicht.</p>

<p class="callout info">Die <strong>Indizierung</strong> stand früher als Schalter <code>index</code> ebenfalls hier. Sie hat inzwischen ein eigenes Feld in der Maske unter <em>Shopdaten</em> und ist im Handbuch <em>FINN.ghost für Shopware 6</em> beschrieben. Ein noch vorhandenes <code>index: true</code> übernimmt FINN.ghost beim Start automatisch als Einstellung <em>Sofort</em>.</p>

## Nächster Schritt

[Shopify](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/shopify)

# Shopify

Alle Schlüssel dieser Seite stehen in der `config.json` im Abschnitt `shopify`. Was der
Artikel- und Bestellabgleich im Regelfall tut, steht im
[Handbuch für Shopify](https://wiki.dako-it.com/books/finnghost-fur-shopify).

## Artikel und Preise

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | ------------------------------------------- |
| `continueSelling` | Feldname | Artikelfeld; liefert es einen Wert, bleibt der Artikel bei Bestand 0 **weiter bestellbar**. |
| `forceTax` | Schalter | überträgt jeden Artikel als **steuerpflichtig**, auch wenn in der SelectLine kein gültiger Steuersatz gefunden wird. |
| `reducedTax` | Wert | Steuercode der SelectLine, der als **ermäßigt** gilt. Vorgabe `2`. Artikel mit diesem Code kommen in die Artikelgruppe für ermäßigte Steuer. |
| `costPricePG` | Wert | Preisgruppe, aus der die **Kosten** je Artikel übertragen werden. Ohne die Angabe gilt der letzte Einkaufspreis aus der Kalkulation. |
| `firstImgToEnd` | Schalter | verschiebt das **erste Bild an das Ende** der Bilderreihe. |
| `disableSafeguardPriceField` | Feldname | Artikelfeld; ist es `True`, wird ein Artikel **ohne Preis** mit Preis 0 übertragen statt übersprungen. |
| `extrafeldMapping` | Liste | benennt Zusatzfelder beim Übertragen um, wie bei Shopware 6. Das Ursprungsfeld wird dabei immer entfernt. |

<p class="callout warning">Ohne <code>disableSafeguardPriceField</code> wird ein Artikel ohne gültigen Preis in Shopify <strong>archiviert</strong> und eine Meldung ins Protokoll geschrieben. Das ist Absicht — ein Artikel mit Preis 0 im Shop ist teurer als ein fehlender.</p>

<p class="callout info"><code>firstImgToEnd</code> wirkt nur bei Artikeln mit mehr als einem Bild. Der Hintergrund: Shopify zeigt das erste Bild als Vorschaubild, die SelectLine sortiert Bilder nach der Ordnung — passt beides nicht zusammen, ist das die schnellste Abhilfe.</p>

<p class="callout warning">Bei <code>continueSelling</code> wird — anders als bei den übrigen Feldern dieses Kapitels — <strong>nicht</strong> auf den Wert <code>True</code> geprüft. Ausgewertet wird nur, ob das Feld überhaupt einen Wert liefert. Ein Ja/Nein-Extrafeld ist hier deshalb die falsche Wahl: Es enthält auch bei <em>Nein</em> einen Wert. Passend ist ein Feld, das für die betroffenen Artikel gefüllt und für alle anderen leer ist.</p>

<p class="callout danger"><code>reducedTax</code> vergleicht den <em>Steuercode</em> des Artikels, nicht den Steuersatz. Bei abweichender Nummerierung der Steuercodes im Mandanten muss der Wert angepasst werden — sonst landen entweder alle oder keine Artikel in der Gruppe für ermäßigte Steuer.</p>

## Artikelgruppen und Aufräumen

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | ------------------------------------------- |
| `shopaktivArtikelGruppenFeld` | Feldname | Feld an der Artikelgruppe; nur Gruppen mit `True` werden übertragen. |
| `deleteUnknownProducts` | Schalter | **archiviert** Produkte im Shop, die in der SelectLine nicht existieren oder nicht mehr shopaktiv sind. |

<p class="callout danger"><code>deleteUnknownProducts</code> greift auf den ganzen Shop zu. Produkte, die im Shop von Hand angelegt wurden und in der SelectLine nicht existieren, werden dabei ebenfalls archiviert. Vor dem Einschalten gehört geprüft, ob es solche Produkte gibt.</p>

## Bestände

Bestand und Bestandsführung stehen auf einer eigenen Seite, weil dort mehrere
Einstellungen zusammenwirken: [Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge).

## Belege

| Schlüssel | Typ | Wirkung |
| ---------------------------------------- | -------- | --------------------------------- |
| `idField` | Feldname | Belegfeld, in dem die **Shopify-Bestellkennung** abgelegt wird. Vorgabe `IhrAuftrag`. |
| `orderTag` | Wert | Kürzel, mit dem die Kennung beginnt. Vorgabe `sfy_`. |
| `mailField` | Feldname | Belegfeld für die **E-Mail-Adresse** des Bestellers. |
| `phoneField` | Feldname | Belegfeld für die **Telefonnummer**. |
| `noteToFooter` | Schalter | schreibt die Kundenanmerkung in den **Schlusstext** statt in den Kopftext. |
| `useSfyPostext` | Schalter | übernimmt den **Positionstext aus Shopify** statt der Artikelbezeichnung aus der SelectLine. Auf 80 Zeichen gekürzt. |
| `documentImportCheckField` | Feldname | Belegfeld, das nach erfolgreichem Import auf `True` gesetzt wird. |
| `tooLongAdrField` | Feldname | Belegfeld, in dem Adressbestandteile über 80 Zeichen vermerkt werden. |
| `simplePrintStatus` | Schalter | erkennt den Versand daran, dass der Lieferschein als **gedruckt** markiert und der Beleg seit dem letzten Lauf bearbeitet wurde — statt am protokollierten Druckvorgang. |
| `mapMarketOrderIdField` | Feldname | Belegfeld für die **Amazon-Bestellnummer** aus den Bestellattributen. Vorgabe `_SFYMARKETORDERID`. |
| `businessPartnerContractDateWithTime` | Schalter | schreibt in das Vertragsdatum zusätzlich die **Uhrzeit**. |
| `noPosCheck` | Schalter | schaltet die Kontrolle ab, ob alle Positionen im Beleg angekommen sind. |
| `useCurrentQuantity` | Schalter | übernimmt die in Shopify **verbleibende Menge** statt der ursprünglich bestellten. In Shopify entfernte Positionen landen dadurch nicht im Beleg. |

<p class="callout danger"><code>idField</code> und <code>orderTag</code> sind die Wiedererkennung einer Bestellung. Werden sie im laufenden Betrieb geändert, findet FINN.ghost die bereits importierten Bestellungen nicht mehr und importiert sie erneut. Beides gehört vor der Inbetriebnahme festgelegt und danach nicht mehr angefasst.</p>

<p class="callout warning"><code>noPosCheck</code> schaltet eine Sicherung ab: Normalerweise vergleicht FINN.ghost nach dem Anlegen die Anzahl der Positionen und bricht mit einem Fehler ab, wenn die SelectLine Positionen verworfen hat. Ohne diese Prüfung entstehen unvollständige Belege, ohne dass es auffällt.</p>

<p class="callout success"><code>useCurrentQuantity</code> ist die Antwort auf entfernte Positionen: Wird eine Bestellung in Shopify nach dem Eingang bearbeitet — eine Position entfernt oder die Menge verringert — bleibt die ursprüngliche Menge (<code>quantity</code>) an der Position stehen, die verbleibende steht in <code>current_quantity</code>. Ohne den Schalter übernimmt FINN.ghost die ursprüngliche Menge und legt entfernte Positionen mit an. Mit dem Schalter zählt die verbleibende Menge; Positionen mit Menge 0 werden übersprungen und ein anteiliger Rabatt wird mitgekürzt. Greift nur bei Bestellungen, die zum Zeitpunkt des Imports bereits bearbeitet waren — ein bestehender Beleg wird nicht nachträglich angepasst.</p>

<p class="callout warning"><code>useCurrentQuantity</code> und die Gutschriftenprüfung (<code>disableRefundCheck</code> auf <code>false</code>) schließen sich aus. Die Gutschriftenprüfung braucht die volle Menge im Auftrag, um daraus die Gutschrift zu bilden — sind die Positionen bereits gekürzt, findet sie die Position nicht mehr und der Import läuft auf einen Fehler.</p>

<p class="callout info"><code>tooLongAdrField</code> ist für Shops mit langen Firmenbezeichnungen gedacht. Die SelectLine nimmt nur 80 Zeichen je Adressfeld — was abgeschnitten wird, ist dann wenigstens am Beleg vermerkt.</p>

<p class="callout success"><code>simplePrintStatus</code> ist die Abhilfe, wenn Versandmeldungen ausbleiben, obwohl Lieferscheine gedruckt werden. Normalerweise liest FINN.ghost den Druckvorgang aus der Belegausgabe — wird in der SelectLine nicht über den regulären Druck ausgegeben, entsteht dort kein Eintrag. Der Schalter wertet dann stattdessen das Kennzeichen <em>Gedruckt</em> am Beleg aus.</p>

### Gutschriften

| Schlüssel | Typ | Wirkung |
| --------------------------------- | ---- | ------------------------------------------------ |
| `belegtyp_gutschrift` | Wert | Belegtyp für Gutschriften. Vorgabe `G`. |
| `belegtyp_gutschriftNoRestock` | Wert | abweichender Belegtyp für Gutschriften **ohne Rücknahme in den Bestand**. |
| `disableRefundCheck` | Schalter | Vorgabe `true`. Mit `false` prüft FINN.ghost auch bei einem Komplettstorno auf Gutschriften. |

<p class="callout success"><code>belegtyp_gutschriftNoRestock</code> ist die Antwort auf eine häufige Anforderung: Wird eine Rücksendung in Shopify ohne Wiedereinlagerung erstattet, soll in der SelectLine ein Belegtyp entstehen, der den Bestand nicht erhöht.</p>

### Zuordnung über Tags und Metafelder

| Schlüssel | Typ | Wirkung |
| ------------------------ | ----- | ------------------------------------------------------ |
| `shopkundeTagMapping` | Liste | ordnet einem **Bestell-Tag** einen anderen Shopkunden zu. |
| `mapMetafields` | Liste | überträgt **Metafelder** der Bestellung in Belegfelder. |
| `presentment_currencies` | Liste | Währungen, in denen Bestellungen zusätzlich importiert werden. |

```json
{
  "shopify": {
    "shopkundeTagMapping": { "b2b": "10001", "haendler": "10002" },
    "mapMetafields": { "custom": { "wunschtermin": "FreiesDatum1" } }
  }
}
```

<p class="callout info">Bei <code>mapMetafields</code> ist die Struktur zweistufig: erst der Namensraum des Metafelds, darin der Schlüssel, dahinter das Ziel-Belegfeld.</p>

## Kunden

| Schlüssel | Typ | Wirkung |
| ------------------------------------ | -------- | --------------------------------------- |
| `kdfeld1` bis `kdfeld9` | Feldname | **weitere** Kundenfelder, in denen bei der Suche nach einem vorhandenen Kunden ebenfalls nach der Shopify-Kundennummer gesucht wird. |
| `customerNumberRange` | Wert | Nummernkreis für neu angelegte Kunden. Die neue Nummer ist die höchste vorhandene Nummer mit diesem Beginn, um eins erhöht. |
| `updateCustomer` | Schalter | aktualisiert vorhandene Kunden beim Bestellimport, auch wenn das Aktualisieren sonst abgeschaltet ist. |
| `sendEmailInviteToNewCustomers` | Schalter | lässt Shopify neu angelegten Kunden eine **Einladung** senden. |

<p class="callout warning">Die Felder <code>kdfeld1</code> bis <code>kdfeld9</code> ergänzen das in der Oberfläche eingestellte Kundenfeld, sie ersetzen es nicht. Ist <code>kdfeld1</code> gesetzt, schreibt FINN.ghost die Kundennummer bei neuen Kunden allerdings <strong>nicht</strong> mehr selbst in das Standardfeld — dann sind diese Felder die einzige Zuordnung und müssen gepflegt sein.</p>

<p class="callout danger">Vor <code>sendEmailInviteToNewCustomers</code> ist zu bedenken, dass Shopify die Mail an jeden neu übertragenen Kunden schickt. Beim ersten Vollabgleich der Kunden aus der SelectLine sind das unter Umständen sehr viele Mails auf einmal.</p>

## B2B mit Shopify Plus

| Schlüssel | Typ | Wirkung |
| --------------------------------- | -------- | ---------------------------------------- |
| `plus.status` | Schalter | schaltet den B2B-Betrieb ein: Kunden werden als **Firmen** übertragen statt als Privatkunden. |
| `plus.checkoutToDraft` | Schalter | Bestellungen der Firma werden als **Entwurf** angelegt und müssen freigegeben werden. |
| `plus.editableShippingAddress` | Schalter | die Lieferadresse darf im Shop geändert werden. |
| `plus.paymentTermsTemplateId` | Wert | Kennung der Zahlungsbedingung, die den Firmen zugewiesen wird. |

<p class="callout danger"><code>plus.status</code> setzt Shopify Plus voraus und ändert die Übertragung grundlegend. Zusätzlich entfällt damit die Prüfung, ob eine Bestellung bezahlt ist — im B2B ist der Rechnungskauf der Regelfall, unbezahlte Bestellungen werden also importiert.</p>

<p class="callout info">Die Kennung für <code>plus.paymentTermsTemplateId</code> ist die reine Nummer der Vorlage aus Shopify; die vollständige Kennung setzt FINN.ghost selbst zusammen.</p>

## Nächster Schritt

[Weitere Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/weitere-module)

# Weitere Module

Was in den übrigen Modulen keine Maske hat — und die Einstellungen, die für die ganze
Installation gelten und deshalb ohne Abschnitt in der `config.json` stehen.

## FINN.webshop

Abschnitt `shop`.

| Schlüssel | Typ | Wirkung |
| ------------------------------ | -------- | ------------------------------------------- |
| `shopaktivArtikelGruppenFeld` | Feldname | Feld an der Artikelgruppe; nur Gruppen mit `True` werden übertragen. |

Die eigene Bestandsabfrage `shop.customStock` steht unter
[Bestand und Bestellmenge](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/bestand-und-bestellmenge).

## Bilder aus dem Dateisystem

Ohne Abschnitt — gilt für alle Module, die Artikelbilder übertragen.

| Schlüssel | Typ | Wirkung |
| ------------ | ---- | ------------------------------------------------------------ |
| `imagePath` | Wert | Ordner, aus dem die Artikelbilder gelesen werden — statt aus der SelectLine. |

Die Dateien werden dem Artikel über den Dateinamen zugeordnet: **Artikelnummer,
Unterstrich, laufende Nummer.**

```text
100815_1.jpg
100815_2.jpg
100815_10.jpg
```

Sortiert wird nach der Zahl hinter dem Unterstrich, und zwar numerisch — `_10` kommt also
nach `_2`, nicht dazwischen.

| | |
| ---------------------------------------- | ------------------------------------- |
| **Ordner enthält Bilder zum Artikel** | diese werden übertragen |
| **Ordner enthält keine passende Datei** | Rückfall auf die Bilder in der SelectLine |
| **Ordner nicht erreichbar** | Fehler; der Lauf bricht ab |

<p class="callout danger">Ist der Ordner nicht erreichbar, wird nicht auf die SelectLine zurückgefallen, sondern der Lauf bricht mit einem Fehler ab. Bei einem Netzwerkpfad braucht das Dienstkonto Leserechte darauf — läuft der Dienst als lokales Systemkonto, hat es auf einem Netzwerkpfad in der Regel keine.</p>

<p class="callout info">Der Rückfall auf die SelectLine gilt je Artikel: Für Artikel mit Dateien im Ordner gelten die Dateien, für alle anderen die Bilder aus der SelectLine. Beides lässt sich also mischen.</p>

<p class="callout warning">Bildformat und Bildqualität aus den Einstellungen gelten auch für diese Dateien — sie werden vor dem Übertragen umgewandelt. Siehe <a href="sys-server">Server und Oberfläche</a>.</p>

## Oberfläche

Ohne Abschnitt.

| Schlüssel | Typ | Wirkung |
| -------------- | -------- | ------------------------------------------------------- |
| `theme` | Wert | Farbe der Oberfläche, als Objekt mit dem Feld `primary`. Vorgabe `#AA1948`. |
| `disableBeep` | Schalter | Vorgabe `true`. Mit `false` gibt die Oberfläche bei einem Fehler einen **Signalton** aus. |
| `onlyCustom` | Schalter | zeigt **ausschließlich** die Seite der individuellen Anpassungen — ohne Menü, ohne Navigation. |

```json
{
  "theme": { "primary": "#1976D2" },
  "disableBeep": false
}
```

<p class="callout danger"><code>onlyCustom</code> verbirgt alle Module samt Einstellungen und Zeitsteuerung. Es ist für Installationen gedacht, die nur eine kundenspezifische Maske bereitstellen, und setzt eine Lizenz für individuelle Anpassungen voraus. Ohne Zugriff auf die <code>config.json</code> kommt man danach nicht mehr an die übrigen Masken.</p>

<p class="callout success">Der Signalton ist nützlich an Arbeitsplätzen, an denen die Oberfläche dauerhaft offen steht und Fehler auffallen sollen — etwa im Lager oder im Versand.</p>

## SelectLine

| Schlüssel | Typ | Wirkung |
| -------------------------------- | -------- | ------------------------------------------- |
| `skipVersionscheck` | Schalter | übergeht die Prüfung, ob die SelectLine-Version mindestens der geforderten entspricht. |
| `slsettings.warehouseCheckColum` | Feldname | Spalte in `LAGERPLATZ`, über die ein Lagerplatz zusätzlich anhand einer Nummer gefunden wird. |

<p class="callout danger"><code>skipVersionscheck</code> ist ausdrücklich ein Notbehelf. Die Mindestversion steht nicht ohne Grund: Fehlen der SelectLine-API Endpunkte, die FINN.ghost erwartet, laufen Übertragungen an unvorhersehbaren Stellen auf Fehler. Der Schalter hilft, eine Installation überhaupt zu starten — die richtige Abhilfe ist das Update der SelectLine.</p>

<p class="callout info"><code>slsettings.warehouseCheckColum</code> wird gebraucht, wenn Lagerplätze aus einem Drittsystem als reine Nummer kommen und nicht als die von der SelectLine erwartete Kombination aus Lager und Dimensionen. Zuerst wird immer regulär gesucht; erst wenn das nichts findet, greift diese Spalte.</p>

## GetMyInvoices

Abschnitt `gmi`.

| Schlüssel | Typ | Wirkung |
| ------------- | -------- | ------------------------------------------------------- |
| `statusField` | Feldname | Belegfeld, in das bei einer **Betragsabweichung** der Hinweis geschrieben wird. Vorgabe `FreierText1`. |

<p class="callout warning">Weicht der Bruttobetrag ab, wird der Beleg nicht als geprüft markiert und der Hinweis samt Abweichung in Prozent in dieses Feld geschrieben. Ist <code>FreierText1</code> im Mandanten anderweitig belegt, gehört hier ein anderes Feld hinterlegt — sonst überschreibt der Abgleich vorhandene Inhalte.</p>

## FINN.mail2SL

Abschnitt `mail2sl`.

| Schlüssel | Typ | Wirkung |
| --------- | ---- | -------------------------------------------------------------- |
| `limit` | Wert | Anzahl der Nachrichten, die je Lauf aus dem Postfach geholt werden. Vorgabe `10`. |

<p class="callout warning">Der Wert begrenzt die Nachrichten <strong>je Lauf</strong>, nicht je Tag. Bei einem Postfach mit hohem Aufkommen kann der Rückstand wachsen, wenn je Lauf weniger Nachrichten verarbeitet werden als neu eintreffen. Dann entweder den Wert erhöhen oder den Lauf häufiger einplanen.</p>

<p class="callout info">Ein höherer Wert verlängert den einzelnen Lauf entsprechend. Kommt es dabei zu Zeitüberschreitungen am Postfach, ist der häufigere Lauf der bessere Weg.</p>

## FINN.AI MCP

Abschnitt `mcp`. Ergänzt die Einstellungen, die die Oberfläche für den KI-Zugang anbietet.

| Schlüssel | Typ | Wirkung |
| ------------------------ | ---- | -------------------------------------------------------- |
| `maxSessions` | Wert | Höchstzahl gleichzeitiger Sitzungen. Vorgabe `50`. |
| `sessionTimeoutSeconds` | Wert | Zeit in Sekunden, nach der eine untätige Sitzung verworfen wird. Vorgabe `1800` (30 Minuten). |
| `bodyLimit` | Wert | Höchstgröße einer Anfrage. Vorgabe `"10mb"`. |

<p class="callout info">Diese drei Werte sind Schutzgrenzen und müssen im Normalbetrieb nicht angefasst werden. Sie sind gedacht für Installationen mit auffällig vielen gleichzeitigen Zugriffen oder mit knappem Speicher auf dem Server.</p>

<p class="callout warning">Bei <code>bodyLimit</code> gehört die Einheit mit in den Wert und der Wert in Anführungszeichen — <code>"10mb"</code>, nicht <code>10</code>.</p>

## Individuelle Anpassungen

Abschnitt `custom`. Diese Schlüssel gehören zu kundenspezifischen Erweiterungen und sind
nur dort gesetzt, wo die passende Anpassung ausgeliefert ist.

| Schlüssel | Typ | Wirkung |
| -------------------------- | ---- | ------------------------------------------------------ |
| `apiport` | Wert | Port einer zusätzlichen Schnittstelle für Fremdsysteme. Ohne die Angabe wird sie nicht gestartet. |
| `apiRechnungDruckvorlage` | Wert | Druckvorlage, mit der über diese Schnittstelle angeforderte Rechnungen erzeugt werden. |

<p class="callout warning">Der Port muss frei sein und darf nicht mit dem Port der Oberfläche zusammenfallen. Fehlt <code>apiRechnungDruckvorlage</code>, beantwortet die Schnittstelle Anfragen nach einer Rechnung mit einem Fehler.</p>

## Nächster Schritt

Zurück zu den [Häufigen Fragen](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/haufige-fragen) oder zur
[Zeitsteuerung der Module](https://wiki.dako-it.com/books/finnghost-systemhandbuch/page/zeitsteuerung-der-module-allgemein).